C# 从基类调用子类的新方法
我上过这样的课C# 从基类调用子类的新方法,c#,methods,new-operator,invoke,base-class,C#,Methods,New Operator,Invoke,Base Class,我上过这样的课 namespace ConsoleApplication1 { class Program { static void Main(string[] args) { A a = new C(); a.method(); Console.ReadLine(); } } public class A { pu
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
A a = new C();
a.method();
Console.ReadLine();
}
}
public class A
{
public virtual void method()
{
Console.WriteLine("METHOD FROM A");
}
}
public class B : A { }
public class C : B
{
public override void method()
{
Console.WriteLine("METHOD FROM C");
}
}
}
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
A a = new C();
a.method();
Console.ReadLine();
}
}
public class A
{
public void method()
{
Console.WriteLine("METHOD FROM A");
}
}
public class B : A { }
public class C : B
{
public new void method()
{
Console.WriteLine("METHOD FROM C");
}
}
}
它工作正常,打印“C中的方法”
但是
如果我遇到这样的情况
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
A a = new C();
a.method();
Console.ReadLine();
}
}
public class A
{
public virtual void method()
{
Console.WriteLine("METHOD FROM A");
}
}
public class B : A { }
public class C : B
{
public override void method()
{
Console.WriteLine("METHOD FROM C");
}
}
}
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
A a = new C();
a.method();
Console.ReadLine();
}
}
public class A
{
public void method()
{
Console.WriteLine("METHOD FROM A");
}
}
public class B : A { }
public class C : B
{
public new void method()
{
Console.WriteLine("METHOD FROM C");
}
}
}
它会打印“来自A的方法”。如果不采用带覆盖的cast或change方法声明,如何获得第一个示例的相同行为?您不能-这种行为上的差异是使用virtual/override的关键 当您用“new”声明一个方法时,您的意思是“我知道我隐藏了一个具有相同签名的方法,而不是覆盖它;我不想要多态行为。” 同样,当您声明一个方法而不指定“virtual”时,您的意思是“我不希望子类能够重写这个方法。” 你为什么要这样做?您实际上只是试图重写一个尚未声明为虚拟的方法吗?如果是这样的话,那就没有办法了——这是有充分理由的。如果作者在设计类时没有考虑多态性,那么如果您能够重写该方法,它可能很容易崩溃 当然,如果您将变量声明为子类的类型,如下所示:
C c = new C();
c.method();
然后,这将调用新声明的方法。就像Jon说的那样,避免使用它。但是
static void Main(string[] args)
{
A a = new C();
(a as C).method();
Console.ReadLine();
}
您可以使用动态关键字调用此方法
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
dynamic a = new C();
a.method();
Console.ReadLine();
}
}
public class A
{
public void method()
{
Console.WriteLine("METHOD FROM A");
}
}
public class B : A { }
public class C : B
{
public new void method()
{
Console.WriteLine("METHOD FROM C");
}
}
}