“新”修饰语的实际用途是什么?
public class Base
{
public void Say()
{
Console.WriteLine("Base");
}
}
public class Derived:Base
{
public new void Say()
{
Console.WriteLine("Derived");
}
}如果这样做不能编译,那不是更好吗?此代码:
Derived d = new Derived();
d.Say();
((Base)d).Say();返回
Derived
Base这不违反Liskov替代原则吗?
干杯。
发布于 2013-12-18 11:16:17
关于LSP
这不会破坏LSP。LSP指出,如果Derived是Base的一个子类型,那么任何依赖于Base的代码(例如,具有Base参数的方法,如void DoSomething(Base b))都可以替换为Derived实例,而不会产生任何令人惊讶的效果。
正如您所指出的,如果将Derived的实例分配给Base变量,则将调用Base实现。
这是预期的行为,因为Say不是虚拟的。这意味着针对Base变量编写的代码期望调用Base实现。
实用目的
您可以将new方法看作是规避不可过的方法的一种方法--但有一个警告!您必须针对特定类型(而不是它的接口)进行编程。
发布于 2013-12-18 11:16:43
虽然这样做并不是一个好的实践,但是当您从第三方程序集继承(即您没有控制权的代码)并且希望对一个方法有不同的行为时,我可以看到它是有用的。
发布于 2013-12-18 11:19:41
如果派生类中的方法具有相同的名称和参数列表,则认为它与基类中的方法“相关”。编译器设计人员有两种处理这些相关方法的方法:
virtual/override指定相关的方法,用new指定无关的方法。处理兴奋方法的第一种方法使程序员别无选择:如果他们想要一个不相关的方法,他们必须给它取一个不同的名字。第二种方法将选择留给程序员,而牺牲了更详细的内容。
本质上,new关键字允许您与编译器通信,说明您添加的方法与基类中具有相同名称和参数的方法无关。
这不违反Liskov替代原则吗?
可以说,它不是这样的:派生类引入了一个名称和参数相同的方法,程序员明确指定该方法与基类中的方法无关,但在将派生类用作基类的替身时,派生类的行为不会发生任何变化。
https://stackoverflow.com/questions/20656480
复制相似问题