0

Given the following code:

interface IParent { void ParentPrintMethod(); } interface IChild : IParent { void ChildPrintMethod(); } class Baby : IChild { public void ParentPrintMethod() { Console.WriteLine("Parent Print Method"); } public void ChildPrintMethod() { Console.WriteLine("Child Print Method"); } } 

All is well at this point. If you were to create a new instance of the Baby class as follows,

Baby x = new Baby(); 

everything is ok, and you would have access to the ParentPrintMethod() and the ChildPrintMethod();

However, can somebody please explain to me what would happen if you were to do the following?

IParent x = new Baby(); 

Would you have access to the ChildPrintMethod() in this case? What exactly is happening when you do this?

7
  • I am testing it, however I'm not understanding exactly why this occurs. It seems to me as if a level of inheritance is skipped and I'm wondering if that's how this works. Commented Mar 11, 2014 at 23:35
  • 1
    Maybe you should describe your experiment and the part that suprises you? Commented Mar 11, 2014 at 23:36
  • 1
    Please name your interfaces starting with I... IParent, IChild, ICanHasCheeseburger, etc. Commented Mar 11, 2014 at 23:43
  • I'm aware of the naming convention, I just skipped out on it in this example. Commented Mar 11, 2014 at 23:50
  • 1
    +1. Thanks for edit. It is your personal choice (which you've clearly stated in your previous comment) to name classes/objects the way you want. Unfortunately most people don't have unlimited time to look at questions - so if your code look strange / not matching title you likely will get comments about style rather than real answers. Note that pretty much everyone spent part of answer on your unusual choice of naming of interface - the same effort could have been spent on making answer to your question better. Commented Mar 12, 2014 at 1:11

5 Answers 5

3

Then you're specifying you're interested only in the Interface declared by Parent so you would only have access to those methods declared in Parent even if the instance of the object itself has more available.

Sign up to request clarification or add additional context in comments.

6 Comments

So it essentially excludes the other methods defined in the class?
It's not excluding them. They're still there. You just don't have access to them because you've specified you're interested in only the methods declared by the interface Parent.
Think of it this way. If you say to someone you want a car, they could give you a 2 door, 4 door, hatchback, convertible, etc. You don't know what kind of car, but you know it's going to be able to work like a car. So when you say you want a Parent object, it doesn't matter what ELSE it can do, as long as it can do whatever is defined by Parent.
Ok, so included, but not accessible. Thanks
No, it is just unknown. It will use its memory and function as a Baby, and is castable like (Baby)x
|
3

No, you would not. The variable x, as type Parent (by the by, interfaces are idiomatically named with an I at the beginning) would only see the methods defined in the Parent interface. Period.

3 Comments

excellent, thank you. So is a level of inheritance skipped? (for lack of better terminology)
You have skipped a level in your declaration, yes. It all depends on what you want to do, whether it's of use or not.
When you're implementing interfaces, you're not inheriting anything. It's a contract you're agreeing to implement. Inheritance implies the child inherits the behavior defined by the parent object. That's what what's happening with interfaces.
2

Your reference to the object will behave like an instance of the Parent interface and will not have access to the Child methods.

Comments

2

This sounds really abnormal but: All Children are Parents, but not all Parents are Children.

It doesn't make sense for a Parent to access a Childs methods because it would be an error in the case that the parent isn't a child.

It is still possible to access the child methods in your example given, but you must cast x to a Child first, ((Child)x).ChildPrintMethod(). This is sound because in the event that x is not a valid Child, an exception is thrown when the cast happens, rather than attempting to run the method.

You can test ahead whether this should work, rather than having to catch exceptions by using if (x is Child)

Edit:

To reuse the variable as if it were a child, you can create a local reference to it like this:

if (x is Child) { Child y = (Child)x; ... } 

3 Comments

Excellent point, thank you. How can you do a more 'permanent' cast?
You can say Child y = (Child)x, or x as Child. The latter one differs in that it returns null if it's not a child, rather than throwing an exception.
Child y = x as Child;, results in a y which is either a valid Child or null otherwise. (The operator as is based on is, which can be read in more detail here: blogs.msdn.com/b/ericlippert/archive/2010/09/16/…)
1

There is no such thing as "inheritance skipped". Your object is just viewed 'through' one of its interfaces, effectively hiding anything else not declared in that interface. There's no magic in it.

1 Comment

Great point, which explains how ((Child)x).ChildPrintMethod() is still able to call the ChildPrintMethod, thank you

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.