简体   繁体   English

C#多态和方法继承

[英]C# Polymorphism and Method Inheritance

Consider the following classes: 考虑以下类:

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;
    }
};

Is there a way to achieve the following desired output? 有没有办法实现以下所需的输出?

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

The issue I am having is that class A's implementation is always being called regardless of the arguments passed. 我遇到的问题是,无论传递的参数如何,都始终会调用A类的实现。

You need to make the foo method in class A virtual so it can be overridden properly and called polymorphically. 你需要在Avirtual使用foo方法,这样它才能被正确覆盖并多态调用。

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

The way you are doing it at the moment, is effectively defining a new method implementation in B and C which will only be called if the instance is of that type. 你现在这样做的方式是在BC有效地定义一个新的方法实现,只有当实例属于那种类型时才会调用它。 Since you are declaring them as type A ( A obj1 = new B(); ) and the method is not virtual then the A implementation will always be called. 由于您将它们声明为类型AA obj1 = new B(); )并且该方法不是虚拟的,因此将始终调用A实现。

I believe you desire to define virtual method and override it with a signature that contains derived types. 我相信您希望定义虚方法并使用包含派生类型的签名覆盖它。 That is not possible as the method that overrides the base one should have the same signature. 这是不可能的,因为覆盖基础的方法应该具有相同的签名。 Probably this is because that would require the compiler to apply complex traversal rules. 可能这是因为这需要编译器应用复杂的遍历规则。 So as suggested in the previous answer to get the desired behavior: 因此,如前面的答案所示,以获得所需的行为:

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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM