Claude Tan
Claude Tan

Reputation: 399

What's is the essential difference between inheritance and interface implementation mechanisms?

Since interface is actually a type, I always regard interface implementation as a special kind of inheritance mechanism, treating the interface as the base type and the type implementing it as a derived type. When an instance of the 'derived' type is created, the methods defined in the 'base' type, I mean the interface, are added into the method table, then the methods defined in this 'derived' type itself are added into the method table too. When there is a 'grandson' type, it will add all methods defined in its father and grandfather(the interface) declaration into its method table. Virtual methods can be overridden of course.

Is my interpretion correct? It seems not to make sense in this scenerio: What if the grandson implements the interface again? like:

interface IFather { void m(); }

class Son: IFather{}

class Grandson : Son, IFather{}

The Grandson adds the methods in the interface into its method table twice?

Upvotes: 0

Views: 60

Answers (1)

mjwills
mjwills

Reputation: 23975

What if the grandson implements the interface again? like:

Run the below code, with and without Grandson implementing IFather and compare the results.

If Grandson implements IFather:

Son Son Son Son Grandson Grandson Son Grandson Grandson Grandson

If Grandson does not implement IFather:

Son Son Son Son Grandson Grandson Son Grandson Son Grandson

Thus, the main scenario in which explicity mentioning that Grandson implements IFather makes a difference in when Grandson shadows / hides a property / method from Son (TypeName in this case). Use of shadowing / hiding is quite uncommon, so in reality there is rarely any difference - specifying that you implement the interface twice generally has no impact (it acts the same as if you specified it once).

using System;

namespace Bob
{
    public interface IFather
    {
        string TypeName { get; }
        string OverridableTypeName { get; }
    }

    public class Son : IFather
    {
        public string TypeName { get; } = "Son";
        public virtual string OverridableTypeName { get; } = "Son";
    }

    public class Grandson : Son //, IFather
    {
        public string TypeName { get; } = "Grandson";
        public override string OverridableTypeName { get; } = "Grandson";
    }

    public class Program
    {
        static void Main(string[] args)
        {
            var son = new Son();

            Console.WriteLine(son.TypeName);
            Console.WriteLine(son.OverridableTypeName);
            Console.WriteLine(((IFather)son).TypeName);
            Console.WriteLine(((IFather)son).OverridableTypeName);

            var grandson = new Grandson();

            Console.WriteLine(grandson.TypeName);
            Console.WriteLine(grandson.OverridableTypeName);
            Console.WriteLine(((Son)grandson).TypeName);
            Console.WriteLine(((Son)grandson).OverridableTypeName);
            Console.WriteLine(((IFather)grandson).TypeName);
            Console.WriteLine(((IFather)grandson).OverridableTypeName);

            Console.ReadLine();
        }
    }
}

Upvotes: 1

Related Questions