“new”关键字(用于方法)和OOP

时间:2014-03-05 03:35:45

标签: c# oop inheritance override

行。我认为我理解newoverride之间的区别。但是,如果我的理解是正确的,那么关于OOP的原则是不是new关键字?有了它,我可以在子类中创建一个方法,该方法具有与基类不同的签名,对吧?像这样:

class MyBase
{
    public int[] SampleMethod() { ... }
}

class MyChild : MyBase
{
    public new string[] SampleMethod() { ... }
}

客户端希望从MyBase继承的类具有名为SampleMethod的方法,该方法返回int数组,但子类不返回。这与override不同,我认为要求子方法与父级具有相同的签名。我错过了什么?

4 个答案:

答案 0 :(得分:5)

问题出在你的陈述中:

  

客户端希望从MyBase继承的类具有一个名为SampleMethod的方法,该方法返回一个int数组,但子类不返回。

这是不真实的。实际上,实现了该方法。只是实现了自己的版本。

如果MyChild的实例被声明为:

MyBase myBase = new MyChild();

这一行:

int[] ints = myBase.SampleMethod();

有效并调用您期望的方法。相比之下,这一行:

string[] strings = myBase.SampleMethod();

会失败。但是,如果将其强制转换为MyChild

string[] strings = ((MyChild)myBase).SampleMethod();

这完全符合您的预期。

这里的要点是,由于变量已知为MyBase,因此无论您的new实现如何,它都会完全按照您的预期行事。因此,多态性 - 因为它对编译时类型做出反应 - 不受影响,并且对任何OOP概念都没有任何暗示。

答案 1 :(得分:2)

我认为适用的原则是Liskov Substitution Principle(LSP),我同意你不应该有一个只在继承类中输出类型不同的方法。通常人们会期望实现类与祖先定义的方法具有相同的语义,无论它是从类型为基类还是实现类的变量引用的。

然而,有原则的是,它们是原则,而不是法律,偶尔也可能违反它们。话虽如此,我不记得长时间使用new关键字来替换父类实现。

我认为需要new方法作为代码气味 - 暗示我的设计可能有问题。也许我试图在那个类层次结构中做太多,或者我选择了错误的模式来应用。

答案 2 :(得分:0)

在继承的接口对方法或属性有更严格的限制的情况下,我更喜欢使用new关键字:

class Car
{
}

class Truck : Car
{
}

interface IDriver
{
    Car Vehicle { get; }
}

class Driver : IDriver
{
    public Car Vehicle { get; }

    public Driver(Car vehicle)
    {
        Vehicle = vehicle;
    }
}

interface ITrucker : IDriver
{
    new Truck Vehicle { get; }
}

class Trucker : Driver, ITrucker
{
    public new Truck Vehicle
    {
        get { return (Truck) base.Vehicle; }
    }

    public Trucker(Truck vehicle)
        : base(vehicle)
    {
    }
}

当我得到一个明确的ITrucker对象时,我直接通过Truck属性获得了它的Vehicle,不需要其他强制转换,在某些情况下非常方便。

无论如何,如果允许设置,则需要仔细处理这些属性。否则,人们会很快得到无效的演员表。对于只读属性,这有时非常方便。

答案 3 :(得分:-1)

它主要用于隐藏基本方法。如果您计划隐藏基类的方法,那么在派生类中标记方法的正确方法。如果不使用new关键字,则会收到编译器警告。

如果您没有具有相同签名的基本方法,则在派生类中使用new是没有意义的。