Why do both the abstract class and interface exist in C#?

前端 未结 11 1931
渐次进展
渐次进展 2020-12-03 00:00

Why do both the abstract class and interface exist in C# if we can achieve the interface feature by making all the members in the class as abstract.

Is it because:

相关标签:
11条回答
  • 2020-12-03 00:27

    It's not a trivial question, it's a very good question and one I always ask any candidates I interview.
    In a nutshell - an abstract base class defines a type hierarchy whereas an interface defines a contract.

    You can see it as is a vs implements a.
    i.e Account could be an abstract base account because you could have a CheckingAccount, a SavingsAccount, etc all which derive from the abstract base class Account. Abstract base classes may also contain non abstract methods, properties and fields just like any normal class. However interfaces only contain abstract methods and properties that must be implemented.

    c# let's you derive from one base class only - single inheritance just like java. However you can implement as many interfaces as you like - this is because an interface is just a contract which your class promises to implement.

    So if I had a class SourceFile then my class could choose to implement ISourceControl which says 'I faithfully promise to implement the methods and properties that ISourceControl requires'

    This is a big area and probably worthy of a better post than the one I've given however I'm short on time but I hope that helps!

    0 讨论(0)
  • 2020-12-03 00:31

    The idea is simple - if your class(YourClass) is already deriving from a parent class(SomeParentClass) and at the same time you want your class(YourClass) to have a new behavior that is defined in some abstract class(SomeAbstractClass), you can't do that by simply deriving from that abstract class(SomeAbstractClass), C# doesn't allow multiple inheritance. However if your new behavior was instead defined in an interface (IYourInterface), you could easily derive from the interface(IYourInterface) along with parent class(SomeParentClass).

    Consider having a class Fruit that is derived by two children(Apple & Banana) as shown below:

    class Fruit
    {
        public virtual string GetColor()
        {
            return string.Empty;
        }
    }
    
    class Apple : Fruit
    {
        public override string GetColor()
        {
            return "Red";
        }
    }
    
    class Banana : Fruit
    {
        public override string GetColor()
        {
            return "Yellow";
        }
    }
    

    We have an existing interface ICloneable in C#. This interface has a single method as shown below, a class that implements this interface guarantees that it can be cloned:

    public interface ICloneable
    {
        object Clone();
    }
    

    Now if I want to make my Apple class(not Banana class) clonable, I can simpley implement ICloneable like this:

     class Apple : Fruit , ICloneable
    {
        public object Clone()
        {
            // add your code here
        }
    
        public override string GetColor()
        {
            return "Red";
        }
    }
    

    Now considering your argument of pure abstract class, if C# had a pure abstract class say Clonable instead of interface IClonable like this:

    abstract class Clonable
    {
        public abstract object Clone();
    }
    

    Could you now make your Apple class clonable by inheriting the abstract Clonable instead of IClonable? like this:

    // Error: Class 'Apple' cannot have multiple base classes: 'Fruit' & 'Clonable'
    class Apple : Fruit, Clonable
    {
        public object Clone()
        {
            // add your code here
        }
    
        public override string GetColor()
        {
            return "Red";
        }
    }
    

    No, you can't, because a class cannot derive from multiple classes.

    0 讨论(0)
  • 2020-12-03 00:34

    They both exist because they are both very different things. Abstract classes permit implementation and interfaces do not. An interface is very handy as it allows me to to say something about the type I am building (it is serializable, it is edible, etc.) but it does not allow me to define any implementation for the members I define.

    An abstract class is more powerful that an interface in the sense that it allows me to create an inheritance interface via abstract and virtual members but also provide some sort of default or base implementation if I so choose. As Spiderman knows, however, with that great power comes great responsibility as an abstract class is more architecturally brittle.

    Side Note: Something interesting to note is that Vance Morrrison (of the CLR team) has speculated about adding default method implementations to interfaces in a future version of the CLR. This would greatly blur the distinction between an interface and an abstract class. See this video for details.

    0 讨论(0)
  • 2020-12-03 00:34

    Interfaces exist to provide a class without any implementation whatsoever, so that .NET can provide support for safe and functional multiple inheritance in a managed environment.

    0 讨论(0)
  • 2020-12-03 00:35

    An Interface defines a contract that an implementing class must fulfil; it is a way of stating that "this does that". An Abstract Class is a partial implementation of a class which is by definition incomplete, and which needs a derviation to be completed. They're very different things.

    0 讨论(0)
  • 2020-12-03 00:39

    Well, an abstract class can specify some implemetation, but usually not all of it. (Having said which, it's perfectly possible to provide an abstract class with no abstract members, but plenty of virtual ones which with "no-op" implementations). An interface provides no implementation, merely a contract.

    You could certainly argue that if multiple inheritance of classes were permitted, interfaces would be largely pointless.

    Personally I don't get hung up on the whole "is-a" vs "can-do" distinction for inheritance. It never gives me as good an intuition about what to do as just playing around with different ideas and seeing which ones feel the most flexible. (Then again, I'm very much a "favour composition over inheritance" guy...)

    EDIT: Just as the most convenient way of rebutting lbushkin's third point in his comment... you can override an abstract method with a non-virtual one (in terms of not being able to override it further) by sealing it:

    public abstract class AbstractBase
    {
        public abstract void Foo();
    }
    
    public class Derived : AbstractBase
    {
        public sealed override void Foo() {}
    }
    

    Classes deriving from Derived cannot override Foo any further.

    I'm not in any way suggesting I want multiple inheritance of implementation - but if we did have it (along with its complexity) then an abstract class which just contained abstract methods would accomplish almost everything that an interface does. (There's the matter of explicit interface implementation, but that's all I can think of at the moment.)

    0 讨论(0)
提交回复
热议问题