0

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

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



AnimalBehaviourBaseClass
 |- ReptileBehaviour 
 |             
 |             
 |
 |- MammalBehaviour

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

我想要一个 AnimalBehaviourBaseClass,它具有所有行为共有的方法。这由 ReptileBehaviour 和 MammalBehaviour 类继承。

从 AnimalBaseClass 继承的类应该只能设置其动物类的行为。所以鳄鱼和蛇只能接受 ReptileBehaviour 及其派生的类。而 Apes 和 Felines 只能接受 MammalBehaviour 及其派生的类。

但实际的 SetCurrentBehaviour 方法对所有动物都是一样的。是否有可能通过多态性改变类型要求以便强制执行?在 AnimalBaseClass 它应该是 SetCurrentBehaviour

在爬行动物中它应该是 SetCurrentBehaviour,在哺乳动物中应该是 SetCurrentBehaviour

当然,我可以向 Reptile 和 Mammal 类添加方法,但原始的 SetCurrentBehaviour från AnimalBaseClass 仍然存在。

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

4

1 回答 1

0

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

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

AnimalBaseClass abc = someCrocodile;

然后,我abc.SetCurrentBehaviour这样调用:

abc.SetCurrentBehaviour(new MammalBehaviour());

这是编译器完全可以接受的。abc是编译时类型AnimalBaseClass,所以它SetCurrentBehaviour接受一个AnimalBehaviourBaseClass. MammalBehaviour是它的子类之一,所以编译器一切正常。但显然,你不想要这个。

解决这个问题的一种方法是向 引入一个泛型类型参数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>
于 2019-07-05T06:01:59.137 回答