Ограничение базового класса параметров типа посредством полиморфизма - PullRequest
0 голосов
/ 05 июля 2019

Это моя цепочка наследования.Есть два из них.Один для животных, другой для поведения животных.

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



AnimalBehaviourBaseClass
 |- ReptileBehaviour 
 |             
 |             
 |
 |- MammalBehaviour

В AnimalBaseClass есть метод SetCurrentBehaviour с параметром типа.

Я хотел бы иметь AnimalBehaviourBaseClass, который имеет методы, которые объединяют все виды поведения.Это наследуется как классами ReptileBehaviour, так и MammalBehaviour.

Классы, унаследованные от AnimalBaseClass, должны иметь возможность только устанавливать поведение его класса животных.Поэтому крокодил и змея могут принимать только поведение ReptileBehaviour и классы, полученные из него.А Обезьяны и Кошачьи могут принимать только MammalBehaviour и классы, вытекающие из него.

Но фактический метод SetCurrentBehaviour одинаков для всех животных.Возможно ли каким-то образом через полиморфизм изменить требование к типу, чтобы оно было принудительным?В AnimalBaseClass он должен использовать SetCurrentBehaviour

в Reptile, это должен быть SetCurrentBehaviour, а в млекопитающих SetCurrentBehaviour

Конечно, я мог бы добавить методы к классам Reptile и Mammal, но тогда оригинальный SetCurrentBehaviourCour был бы еще большетам.

Может быть, я не думаю об этом правильно в соответствии с ООП и C #?

1 Ответ

0 голосов
/ 05 июля 2019

То, что вы пытаетесь сделать (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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...