Polymorphic多态在C#new, virutal, override, sealed
New 是指隐藏父类的方法
Virtual 是指允许子类覆盖
Override 是覆盖父类的Virtual方法
Sealed 是指不可再被继承
1. static 方法不可被继承
2. C#编译器会提出警告,并且会自动加上new, 比如你新建了一个类,并且试图override ToString方法,但如果你不使用override,编译器会给出警告,实际上在IL中会自动加上new
3. sealed override 不可以再被覆盖,但子类可以使用new 或 newvirtual, 而且父类必须使用了virutal, 它与override的区别在于override 可以在子类继续使用 override
classA
{
public virtual void F() {
Console.WriteLine("A.F");
}
public virtual void G() {
Console.WriteLine("A.G");
}
}
classB: A
{
sealed override public void F() {
Console.WriteLine("B.F");
}
override public void G() {
Console.WriteLine("B.G");
}
}
classC: B
{
override public void G() {
Console.WriteLine("C.G");
}
}
4. 使用了virutal,子类如果在使用virtual则应该加上new, 这时子类也可以使用override.
5. override 要求父类被覆盖的方法必须是override(它的始祖是virtual)或virutal 而且不能是private (编译错误,virual 和 private 不能同时使用),这一点和Java不同, Java 会让父类的该private方法隐藏不覆盖
6. 可见性的要求. C# 如果不制定可见性,默认是private,而Java默认是包可见。使用virtual 是, 必须使用protected或public 对应的子类也必须是protected(当父类是protected)/public(当父类是public), 这也和Java不一样, Java 要求父类到子类的可见性应该扩大
7. 只有明确使用了override才能表示该方法被覆盖了,这个Java默认的隐式覆盖有明显区别,接下来我们看几个例子
public interface IInterface
{
void Method();
}
public class MyImpl1 : IInterface
{
public void Method()
{
Console.WriteLine("MyImpl1 - Method");
}
}
public class MyImpl2 : MyImpl1
{
public void Method()
{
Console.WriteLine("MyImpl2 - Method");
}
}
IInterface iinf= new MyImpl2();
iinf.Method(); // 输出 :MyImpl1 - Method
MyImpl2MyImpl2 = new MyImpl2();
MyImpl2.Method(); // 输出 :MyImpl2- Method
((MyImpl1)MyImpl2).Method(); // 输出 :MyImpl1 - Method
public class MyImpl1 : IInterface
{
public virtual void Method()
{
Console.WriteLine("MyImpl1 - Method");
}
}
public class MyImpl2 : MyImpl1
{
public override void Method()
{
Console.WriteLine("MyImpl2 - Method");
}
}
IInterface iinf= new MyImpl2();
iinf.Method(); // 输出 :MyImpl2 – Method
MyImpl2MyImpl2 = new MyImpl2();
MyImpl2.Method(); //输出 :MyImpl2 – Method
((MyImpl1)MyImpl2).Method() ;//输出 :MyImpl2 – Method