通过多态性限制类型参数基类

时间:2019-07-05 01:56:44

标签: c# polymorphism

这是我的继承链。有两个。一种用于动物,另一种用于动物行为。

AnimalBaseClass
|- Reptile 
|           |-  Crocodile
|           |- Snake
|
|- Mammals
            |- Apes
            |- Felines



AnimalBehaviourBaseClass
 |- ReptileBehaviour 
 |             
 |             
 |
 |- MammalBehaviour

AnimalBaseClass有一个带有类型参数的名为SetCurrentBehaviour的方法。

我想拥有一个AnimalBehaviourBaseClass,该类具有所有行为共有的方法。 这是ReptileBehaviour和MammalBehaviour类都继承的。

从AnimalBaseClass继承的类只能设置其动物类的行为。因此,鳄鱼和蛇只能接受ReptileBehaviour及其派生类。猿猴和猫科动物只能接受哺乳动物行为及其衍生的类。

但是,所有动物的实际SetCurrentBehaviour方法都是相同的。是否可能通过多态性改变类型要求以使其得以执行? 在AnimalBaseClass中,应该使用SetCurrentBehaviour

在爬行动物中,应该设置为SetCurrentBehaviour 在哺乳动物SetCurrentBehaviour

当然,我可以将方法添加到Reptile和Mammal类,但是最初的SetCurrentBehaviour和AnimalBaseClass仍然存在。

根据OOP和C#,也许我没有正确考虑这个问题?

1 个答案:

答案 0 :(得分:0)

您试图做的事情(每个类的SetCurrentBehaviour接受不同的类型)将无法实现您真正想要的(只能将行为设置为相应类型的动物)。

假设我将Crocodile的实例分配给AnimalBaseClass变量:

AnimalBaseClass abc = someCrocodile;

然后,我这样叫abc.SetCurrentBehaviour

abc.SetCurrentBehaviour(new MammalBehaviour());

这是编译器完全可以接受的。 abc的编译时类型为AnimalBaseClass,因此其SetCurrentBehaviour接受AnimalBehaviourBaseClassMammalBehaviour是其子类之一,因此编译器可以正常运行。但是显然,您不想要这个。

解决此问题的一种方法是向AnimalBaseClass引入一个通用类型参数,称为TBehaviour

class AnimalBaseClass<TBehaviour> where TBehaviour : AnimalBehaviourBaseClass {
    public void SetCurrentBehaviour(TBehaviour b) { ... } // note the type of parameter
}

在动物子类中,执行以下操作:

class Reptile : AnimalBaseClass<ReptileBehaviour>
class Mammal : AnimalBaseClass<MammalBehaviour>
相关问题