0

When a child class inherits from both a parent class and an interface, why can the child class not access a parent class method?

Consider the following, where I can't access the DoSomething() method.

class Program
{
    static void Main(string[] args)
    {
        IMyInterface myClass = null;
        myClass = new ChildClass();
        // this returns error
        myClass.DoSomething();
    }
}

internal class ParentClass
{
    public ParentClass() { }

    public void DoSomething() { }
}

internal class ChildClass : ParentClass, IMyInterface
{
    public string MyProperty { get; set; }

    public ChildClass() : base() { }
}

internal interface IMyInterface
{
    string MyProperty { get; set; }
}

I've looked through SO discussions here and here, but they seem to focus on how a member is hidden using new, override, and virtual keywords... sorry, but I can't figure out how that applies to this situation. Also, I've browsed through the MSDN API reference on interfaces here and here, with no luck.

Community
  • 1
  • 1
Aaron Thomas
  • 5,054
  • 8
  • 43
  • 89
  • 1
    Because you declare `myClass` as an `IMyInterface`, which does not have a definition for `DoSomething`. – Ron Beyer Nov 17 '15 at 18:07

5 Answers5

4

The problem here is specifically to do with the declaration of the variable in your Main method.

    IMyInterface myClass = null;
    myClass = new ChildClass();
    // this returns error
    myClass.DoSomething();

Taking lines in isolation, we can reduce it to just this.

    IMyInterface myClass = null;

    // BLAH BLAH myClass gets initialized somehow, we don't know/care how.

    myClass.DoSomething();

So at that point, we only know we have an initialized object of interface IMyInterface. In other words, taking that line alone, we don't know that it's a ChildClass. The only known method of IMyInterface is MyProperty, so that's the only thing we know is available to us.

You could fix this by declaring myClass specifically as a ChildClass instance. You can even return this variable in a method that expects to return an IMyInterface type.

Katana314
  • 8,429
  • 2
  • 28
  • 36
2

This does not work for a very straightforward reason:
IMyInterface does not have a DoSomething method.

If you modify your interface as follows, your code will work.

internal interface IMyInterface
{
    string MyProperty { get; set; }
    void DoSomething();
}
Timothy Shields
  • 75,459
  • 18
  • 120
  • 173
  • Are you sure just changing the interface will "make it work"? The child class would have to explicitly implement the interface because it would not automatically be implemented by the parent class by virtue of them having the same name/parameters... – Ron Beyer Nov 17 '15 at 18:10
  • 1
    @RonBeyer `ChildClass` inherits from `ParentClass`, which has a `public void DoSomething()` method. So the `ChildClass` does fully implement the modified `IMyInterface`. – Timothy Shields Nov 17 '15 at 18:12
  • 1
    Interesting, I didn't realize you could project an interface like that since its not marked as virtual or abstract on the base class, and the base class does not implement the interface. – Ron Beyer Nov 17 '15 at 18:17
1

DoSomething() is from ParentClass, and you are using an IMyInterface reference.

To use this method, you need to do a cast:

((ChildClass) myClass).DoSomething();

or

((ParentClass) myClass).DoSomething();
Renan Araújo
  • 3,533
  • 11
  • 39
  • 49
0

Because the type of myClass is IMyInterface:

IMyInterface myClass = null;

and IMyInterface doesn't have a DoSomething() method:

internal interface IMyInterface
{
    string MyProperty { get; set; }
}

However, with polymorphism the type cal also be ParentClass or ChildClass. So you can use the method by morphing the type:

(myClass as ChildClass).DoSomething();

As with any time you cast or morph the type of an object, be careful for nulls. If the type can't be converted then myClass as ChildClass would be null, so the above would result in a NullReferenceException.

David
  • 208,112
  • 36
  • 198
  • 279
0

The best way to understand this is to know the difference between an interface and a parent/child class.

An interface is a contract that can exist on any class regardless of it's inheritance chain. You could put that interface on a class that doesn't inherit from ParentClass, and all that class has to fulfill is what is in your interface (in your case, the MyProperty property). If you added DoSomething() to the interface, this class would then also be required to have that method.

A subclass (child class) inheriting from a parent class has established a relationship. The parent class shares it's non-private methods/properties/member subset with it's child class. Therefore, you can cast a child class to it's parent class and retain accessibility to those properties.