12

Let's say I have an interface as follows.

interface CardHolder : IEnumerable<Card>
{
    /// <summary> ...
    void PutCard(Card card);

    /// <summary> ...
    void PutCards(Card[] card);

    /// Some more methods...
}

I implement it as follows.

public class ArrayCardHolder : CardHolder
{
    private Card[] _cards;
    private int _size = 0;

    public ArrayCardHolder(int capacity)
    {
        _cards = new Card[capacity];
    }

    public void PutCard(Card card)
    {
        if (IsFull())
            throw new Exception("This CardHolder is full. Capacity: " + Capacity());

        _cards[_size++] = card;
    }

    public void PutCards(Card[] cards)
    {
        if (_size + cards.Length > _cards.Length)
            throw new Exception("Adding the Cards would exceed this CardHolder its capacity. Capacity: " + Capacity());

        for (int index = 0; index < cards.Length; index++)
            _cards[_size++] = cards[index];
    }
    public IEnumerator<Card> GetEnumerator()
    {
        for (int index = 0; index < _size; index++)
            yield return _cards[index];
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }

    ///More methods.

}

Why can I not use the override keyword in my ArrayCardHolder (e.g. public void override PutCard(Card card) { ///implementation } to indicate that the method implements (i.e. overrides) the interface? In that case, the project will refuse to build.

Why does it work however when overriding ToString()? And why doesn't it work when implementing CompareTo(T t) from IComparable<T>?

What should I use instead? I'm worried that the documentation from the interface will not apply to my implementing methods. Such is the case in Java when the @Override annotation is used.

Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
Auberon
  • 665
  • 2
  • 7
  • 23
  • 2
    That's just not what `override` means. `override` implies an implementation that is being overridden, such as in a base class. With an interface, there's no implementation to override, so the keyword doesn't make sense. – adv12 Jul 08 '16 at 18:39
  • 1
    You're implementing an interface, you don't need to write override keyword. You need use it for abstract classes and classes – Artavazd Balayan Jul 08 '16 at 18:39
  • 1
    Possible duplicate of [Interface vs Abstract Class (general OO)](http://stackoverflow.com/questions/761194/interface-vs-abstract-class-general-oo) – David L Jul 08 '16 at 18:42
  • 1
    It's weird and counterintuitive but you just learn to live with it. No language is perfect and this is a pretty harmless quirk. as quirks go: Consider Python's closure horror, for example. – 15ee8f99-57ff-4f92-890c-b56153 Jul 08 '16 at 18:42
  • Its very intuitive IMO how can you override something that is not implemented, THAT would be very counterintuitive. It does not even make sense. – Paul Swetz Jul 08 '16 at 18:48
  • My main reason for posting this question was to know if my documentation written in the interface will carry over to the implementing class. – Auberon Jul 08 '16 at 18:55
  • @PaulSwetz No, it's totally nonsensical as it is. Sorry. – 15ee8f99-57ff-4f92-890c-b56153 Jul 09 '16 at 02:32
  • @Auberon Do you mean /// comments? That's an empirical question, easily answered. – 15ee8f99-57ff-4f92-890c-b56153 Jul 09 '16 at 02:33
  • @EdPlunkett. I think interfaces in C# are non sensical in general. For starters, it is weird how properties/fields are allowed in an interface. Additionally, I couldn't find a doc generator in the IDE (Visual Studio), only third party projects, as if you're not supppsed to generate documentation. This all makes me think that C# is a bad language to **design** software in, as opposed to e.g. Java. – Auberon Jul 09 '16 at 09:29
  • @Auberon You can't put fields in interfaces in C#, just properties. I don't see that as weird; properties are syntactic sugar around accessor methods, and the way they're used, they have to be in interfaces. IList, for example. Not sure what that has to do with designing software though. As for generating docs, that might be a nice feature. – 15ee8f99-57ff-4f92-890c-b56153 Jul 09 '16 at 10:13
  • The use of the override keyword on interface implementations - or perhaps of a better named keyword for this particular purpose - would have the advantage of telling you when you think you are implementing a method from an interface but the interface has changed. I guess there are other ways of achieving this, but a keyword is perhaps the less verbose? – Marco Craveiro Apr 20 '21 at 16:23
  • @PaulSwetz I don't understand your argument for why it makes sense to you. "how can you override something that is not implemented" - but this is precisely what you do when you override an `abstract` method in an abstract class. In that case too the method isn't implemented, yet you are overriding it anyway. – amy May 26 '21 at 17:21
  • The beauty of the override is that when you remove the virtual method, the override method becomes invalid so I know to remove it. It would be awesome of something similar happened with interface implementations ... sadly no. UPDATE: apparently in c#8 you can mark interface methods virtual. – Fred Haslam Mar 28 '23 at 23:36

6 Answers6

25

Interface's methods are not overriden, they are implemented. You are confused with abstract/virtual methods which can be overriden.

Example:

public interface IFoo    
{
    void DoA();
}

public abstract class BaseFoo : IFoo
{
    public void DoA() { } // *this HAS to be implemented*
    public virtual void DoB() { } 
}

public abstract class MyFoo : BaseFoo
{
    // *this CAN be implemented, which would override the default implementation*
    public override void DoB() { } 
}

As others metioned, ToString is a virtual method of the base class object, that is why you can override it.

Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
  • Well, by common sense you cannot override abstract method, since it does not have implementation. And you can override interface method, if it have default implementation. I think your first paragraph may be somewhat confusing. But yes, in C# you don't need `override` with interface methods, and you do need it with `abstract`, `virtual` and `override` methods. – Alex Che Jun 20 '23 at 18:24
4

You can override any method of base type if it is marked as virtual. For example you can override ToString() method as it is marked virtual in object class. And object is the base type in .Net.

enter image description here

 public override string ToString()
    {
        return base.ToString();
    }

Interfaces are implemented because they done have any implementation, hence there is nothing to override. For Example IComparable is an interface with CompateTo() method, It has no implementation, Hence you implement it in the class inheriting this interface.

enter image description here

public int CompareTo(object obj)
    {
        throw new NotImplementedException();
    }

I hope I made it clear.

Saket Choubey
  • 916
  • 6
  • 11
3

As mentioned abundantly, override applies to virtual and abstract method implementations, not interface method implementations.

The annoying thing about all of this is that there is no way to generate warnings when a method that used to implement an interface method becomes orphaned.

Interestingly, java tooling has an option to allow @override on interface methods, so that errors/warnings will be generated when an interface method becomes orphaned.

The question, from a language implementation point of view would be whether an override of a interfacement method would be virtual or not. I suppose "override virtual" would be an option. Or "override abstract".

https://github.com/dotnet/csharplang/issues/3510

So technically, the answer to WHY is not "because you can't", but something deeper and more sinister; namely: because the C# language spec is wrong. Just saying. :-P

Robin Davies
  • 7,547
  • 1
  • 35
  • 50
1

An "interface" is a description of "what the public-facing face of some particular programming-thing must look like."

Any "concrete implementation" of that interface must do (at least) everything that the interface called for. (How it "gets 'er done" is entirely up to the implementor.)

So now, let's say that you've got two classes, Dad and Teenager, both of whom implement the same interface. But Teenager (although obviously a descendent of Dad) wants to do one of those things ... say, play_music ... a little bit differently. Teenager can override Dad's method.

So long as Teenager's implementation continues to conform to the strictures of the interface, our teen can play his music just as loudly as he likes.

Mike Robinson
  • 8,490
  • 5
  • 28
  • 41
0

You are not overriding methods, you are implementing members of an interface.

In C#, override is only used when you are overriding an existing implementation. A case of this is ToString(). The method you are overriding must be marked virtual on the base class.

driis
  • 161,458
  • 45
  • 265
  • 341
0

.ToString is a virtual method in a base class Object . That's why you can override it. But you don't override an interface method, you implement it.

If you want to provide a default implementation and maybe override it in a class, then you need to use a base class with a virtual method. So :

Interface method: You must provide implementation in the class.

Abstract method: You must provide implementation in the derived class.

virtual method: you may provide implementation in the derived class or keep the default implementation. (or mix both by calling base.MethodName(); then providing additional code)

Example:

public interface IContract
{
    // It is a must to implement this method in classes
    void MustImplement();
}

public abstract class BaseClass
{
    // Just signature, No implementation. It is a must to implement.
    public abstract void IAmAbstract();

    public virtual void IAmVirtual()
    {
        Console.WriteLine("I provide default implementation");
    }
}

public class DerivedClass : BaseClass, IContract
{
    public override void IAmAbstract()
    {
        Console.WriteLine("provides Abstract Method implementation In Derived Class");
    }

    // It is optional to override this method
    public override void IAmVirtual()
    {
        // class default implementation
        base.IAmVirtual();

        Console.WriteLine("provides Additional virtual Method implementation In Derived Class");
    }

    public void MustImplement()
    {
        Console.WriteLine("provides Interface Method implementation In Derived Class");
    }
}
Zein Makki
  • 29,485
  • 6
  • 52
  • 63