我想知道虽然继承可以用来继承派生类中的属性和方法。
为什么我们不在派生类中编写函数而是将它们声明为覆盖。
以下示例将详细解释我的问题。
class Net
{
public virtual void Act()
{
}
}
class Perl : Net
{
public override void Act()
{
Console.WriteLine("Perl.Act");
}
}
class Python : Net
{
public override void Act()
{
Console.WriteLine("Python.Act");
}
}
// Use base class and derived types in a List.
List<Net> nets = new List<Net>();
nets.Add(new Perl());
nets.Add(new Python());
// Call virtual method on each instance.
foreach (Net net in nets)
{
net.Act();
}
在上面的示例中,act函数可以声明为“NEW”函数为什么我们应该选择覆盖基函数?
编辑:假设我有一个案例如下
class Net
{
public virtual void Act()
{
}
public virtual void secondMethod()
{
}
}
class Perl
{
public override void Act()
{
Console.WriteLine("Perl.Act");
}
public override void secondMethod()
{
Console.WriteLine("Perl.Act");
}
}
class Python
{
public new void Act()
{
Console.WriteLine("Python.Act");
}
public override void secondMethod()
{
Console.WriteLine("Perl.Act");
}
}
那我该怎么办? 在上面的例子中,我希望继承基类,但我实现的功能可能不同。 在这种情况下,我应该使用覆盖或写一个完全不同的方法。
答案 0 :(得分:4)
因为在您的基类上没有virtual
方法,您将无法使用循环调用Act
:
foreach (Net net in nets)
{
net.Act();
}
并且foreach
不是唯一可以使用它的地方。想象一下,您有一个名为Foo
的方法,它将Net
实例作为参数:
public static void Foo(Net net)
{
net.Act();
}
您仍然可以将Python
和Perl
传递给该方法,并且他们都将执行自己的Act
方法逻辑。
virtual
在您想要提供一些基本的默认功能并且能够在派生类中默认override
的任何地方都很有用。
您应该阅读Knowing When to Use Override and New Keywords (C# Programming Guide)
答案 1 :(得分:3)
new
关键字用于方法隐藏,主要用于版本控制目的,但请注意,这两种方法在派生类中仍然可用!并且可以使用简单的cast
访问。但另一方面,使用方法覆盖,您可以覆盖行为(这就是我们所说的多态),因此在派生类中,重写的方法将完全替换基本方法,因此无法访问通过派生类的实例,即使对基类进行向上转换!因为虚方法被重写方法替换。
让我用一个例子向你展示这个概念:
public class Base
{
public virtual void VirtualMethod() { }
public void NewMethod() { }
}
public class Derived : Base
{
public override void VirtualMethod() { }
public new void NewMethod() { }
}
...
Base derived = new Derived();
derived.VirtualMethod(); // Derived.VirtualMethod()
derived.NewMethod(); // Base.NewMethod()
((Derived)derived).NewMethod(); // Derived.NewMethod()
答案 2 :(得分:1)
在上面的示例中,act函数可以声明为“NEW”函数为什么我们应该选择覆盖基函数
继承是指在必要时使用基类提供的额外功能。如果你不想使用基类的功能,为什么你会首先继承?