2015-05-18 83 views
4

考虑下面的类:C#多态性与方法继承

public class X {}; 
public class Y : X {}; 
public class Z : X {}; 

public class A { 
    public bool foo (X bar) { 
     return false; 
    } 
}; 

public class B : A { 
    public bool foo (Y bar) { 
     return true; 
    } 
};  

public class C : A { 
    public bool foo (Z bar) { 
     return true; 
    } 
}; 

有没有办法实现以下所需的输出?

A obj1 = new B(); 
A obj2 = new C(); 

obj1.foo(new Y()); // This should run class B's implementation and return true 
obj1.foo(new Z()); // This should default to class A's implementation and return false 

obj2.foo(new Y()); // This should default to class A's implementation and return false 
obj2.foo(new Z()); // This should run class C's implementation and return true 

我遇到的问题是,不管传递的参数如何,都会调用类A的实现。

回答

3

我相信你希望定义虚拟方法并用包含派生类型的签名覆盖它。这是不可能的,因为覆盖基本方法的方法应该具有相同的签名。可能这是因为这需要编译器应用复杂的遍历规则。正如前面的答案中所建议的,以获得所需的行为:

public class A { public virtual bool Foo (X bar) { ... } } 
public class B { 
    public override bool Foo (X bar) { 
     if(bar is Y) { ... } 
     else base.Foo(bar); 
    } 
} 
+0

有没有办法说,将'obj1'转换为'B'类型以获得所需的行为? –

+0

@DanBrenner当然:'((B)obj1).foo(new Y());'应该根据需要返回'true'。但我需要一些“糖”。 – Artyom

5

您需要在类Avirtual中制作foo方法,以便它可以正确覆盖并进行多态调用。

public class A { public virtual bool Foo (X bar) { ... } } 
public class B { public override bool Foo (X bar) { ... } } 

你此刻在做它的方式,有效地定义在BC一种新的方法实现,如果该实例是该类型的这只会被调用。由于您声明它们为AA obj1 = new B();),并且该方法不是虚拟的,因此将始终调用A实现。

+0

但是,如果我调用'obj1.Foo(new Z());'它将返回true。期望的行为是它返回false。除非参数的类型是'Y',否则'B'类不应该调用它自己的'Foo()'。 –

+0

这可以正确解决您的问题,您可以在方法内实现任何想要的逻辑,甚至可以通过'base.Foo(bar)'调用基本实现。 –