为什么我不能覆盖我的界面呢?

时间:2016-07-08 18:36:46

标签: c# interface override

我们说我的界面如下。

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

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

    /// Some more methods...
}

我按如下方式实施。

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.

}

为什么我的override无法使用ArrayCardHolder关键字 (例如public void override PutCard(Card card) { ///implementation }表示该方法实现(即覆盖)接口?在这种情况下,项目将拒绝构建。

为什么在覆盖ToString()时会有效?从CompareTo(T t)实施IComparable<T>后,为什么它不起作用?

我应该使用什么?我担心界面中的文档不适用于我的实现方法。使用@Override注释时,Java就是这种情况。

6 个答案:

答案 0 :(得分:8)

接口的方法不是覆盖,它们是实现的。您对抽象/虚拟方法感到困惑,可以覆盖它。

示例:

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() { } 
}

正如其他人所提到的,ToString是基类virtual的{​​{1}}方法,这就是覆盖的原因。

答案 1 :(得分:2)

如果标记为虚拟,则可以覆盖任何基本类型的方法。例如,您可以覆盖ToString()方法,因为它在对象类中标记为虚拟。而object是.Net中的基类型。

enter image description here

Html.DropDownListFor

实现接口是因为它们完成了任何实现,因此没有什么可以覆盖。例如,IComparable是一个使用CompateTo()方法的接口,它没有实现,因此您在继承此接口的类中实现它。

enter image description here

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

我希望我说清楚。

答案 2 :(得分:1)

“界面”是描述“某些特定编程事物面向公众的面孔必须是什么样的。”

该接口的任何“具体实现”必须(至少)执行接口所要求的所有内容。 它如何“完成”完全取决于实现者。)

现在,让我们说你有两个类DadTeenager,两个implement同一个界面。但Teenager(虽然显然是Dad的后代)想要做一个这些事情......比如,play_music ......有点不同。 Teenager可以覆盖 Dad的方法。

只要Teenager的实施继续符合界面的限制,我们的青少年就可以像他喜欢的那样大声播放他的音乐。

答案 3 :(得分:0)

您不是重写方法,而是实现接口的成员。

在C#中,仅在覆盖现有实现时使用覆盖。一个例子是ToString()。您覆盖的方法必须在基类上标记为 virtual

答案 4 :(得分:0)

.ToString是基类Object中的虚方法。这就是你可以覆盖它的原因。但是你没有覆盖接口方法,你实现它。

如果要提供默认实现并可能在类中覆盖它,则需要使用带有虚方法的基类。所以:

接口方法:您必须在类中提供实现。

抽象方法:您必须在派生类中提供实现。

虚方法:您可以在派生类中提供实现或保留默认实现。 (或通过调用base.MethodName();混合然后提供其他代码)

示例:

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");
    }
}

答案 5 :(得分:0)

如前所述,重写适用于虚拟方法和抽象方法的实现,而不适用于接口方法的实现。

所有这些令人讨厌的事情是,当用于实现接口方法的方法变得孤立时,无法生成警告。

有趣的是,java工具提供了一个选项,允许在接口方法上使用@override,以便在接口方法变得孤立时会生成错误/警告。

从语言实现的角度来看,问题是接口方法的替代是否是虚拟的。我认为“替代虚拟”将是一个选择。或“替代摘要”。

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

因此,从技术上讲,对“为什么”的答案不是“因为你做不到”,而是更深刻,更险恶的事情;即:因为C#语言规范错误。只是说。 :-P