27.10.2017 Сложное (многоклассовое) наследование и полиморфизм - возможно или нет?
 
Сложное (многоклассовое) наследование и полиморфизм — возможно или нет?

Когда я сталкивался ранее с наследованием классов и полиморфизмом, то это было или,

1) дописывание каких то новых методов в класс-потомок, которых не было в классе-предка. (обычное наследование).
2) переопределение некоторых методов, объявленных в базовом классе как virtual, (обычный полиморфизм), причем сигнатурна методов оставалась одинаковой.

А можно ли унаследовать сразу множество связанных классов? Т.е. как бы целый проект из связных классов, унаследуется от базового проекта, тех же классов,
каждый в своем множестве унаследован от класса-прототипа в базовом проекте.
Чтобы было понятнее, что имеется в виду, 1) упростим задачу до предела — множество из 2-х классов, должно унаследоваться от другого множества из 2-х классов.
(на практике, если есть такая возможность с двумя, то можно хоть 10, хоть 100, хоть любое количество классов в множестве унаследовать).
2) напишу на псевдо-C# языке, чтобы было понятнее, что имею в виду.


Допустим, ранее был написан некий проект с названием Module, который для простоты, состоит из 2-х классов.
Позже, нам нужно эти два класса унаследовать в проекте Special, который как бы, расширяет возможности Module-проекта.

//------------------------------

// Получается, в простейшем варианте, проект Module, допустим, состоял из двух работоспособных классов.


public class ModuleEntity // некая сущность в базовом проекте Module
{
public int ab;
public int cd; // некие поля описывающие сущность
}



public class ModuleAlgorithmic // некая сущность в базовом проекте Module
{
public ModuleEntity entity;

public virtual ModuleEntity[] AlgorithmOfModule(ModuleEntity param)
{
// ...
}
}



//------------------------------

// Как нужно унаследовать сразу два класса. В новом проекте Special.


public class SpecialEntity : ModuleEntity // некая сущность в базовом проекте Module. Наследование этого класса понятно.
{
public int ef; // ну и понятно, будут доступны ab, cd от ModuleEntity
}

//------------------------------

А вот дальше, нам нужно унаследовать класс SpecialAlgorithmic от ModuleAlgorithmic, да так, чтобы 1) его единственное поле ModuleEntity entity;
просто стало полем унаследуемого типа, SpecialEntity entity; 2) Метод AlgorithmOfModule — нужно переопределить (override), да так, что
его сигнатура "почти такая же", но не совсем — этот метод должен уже принимать унаследуемые ссылки на SpecialEntity вместо ModuleEntity.
Т.е. как написать что то типа такого (привожу на псевдо-языке, но должно быть понятно, что имеется в виду).



public class SpecialAlgorithmic : ModuleAlgorithmic // некая сущность в базовом проекте Module
{
public SpecialEntity entity : override ModuleEntity entity; // override field from ModuleAlgorithmic class — field entity

public override SpecialEntity[] AlgorithmOfModule(SpecialEntity param) : ModuleEntity[] AlgorithmOfModule(ModuleEntity param)
{
// ...
}
}


//------------------------------


Что же в таком случае получается? Допустим у нас первый проект, с классами ModuleEntity, ModuleAlgorithmic — полностью работоспособный,
и выводит некий результат после


ModuleEntity param = new ModuleEntity( /* ... */ );
ModuleEntity modEnt = new ModuleEntity( /* параметры создающие объект */ );
ModuleAlgorithmic modAlg = new ModuleAlgorithmic(modEnt); // приняв modEnt, запишет в поле entity
ModuleEntity[] result = modAlg.AlgorithmOfModule(param) // где param — тоже ModuleEntity


// нам нужно получить точно такой же результат, если заменим в этом блоке из 4 строк, все "Module" на "Special"


SpecialEntity param = new SpecialEntity( /* ... */ );
SpecialEntity modEnt = new SpecialEntity( /* параметры создающие объект */ ); // здесь проблем нет — унаследовано и добавлено поле int ef;
SpecialAlgorithmic modAlg = new SpecialAlgorithmic(modEnt); // приняв modEnt, запишет в поле entity !! но уже в SpecialEntity entity : который override (не ModuleEntity типа)
SpecialEntity[] result = modAlg.AlgorithmOfModule(param) // где param — тоже ModuleEntity , но точнее — унаследуемый тип SpecialEntity от ModuleEntity


//------------------------------


Казалось бы, всё просто — унаследовали SpecialEntity от ModuleEntity, добавив ему поле (здесь проблем нет).
Второе — унаследовали SpecialAlgorithmic от ModuleAlgorithmic, чтобы в конечном итоге можно было вызвать точно такой же код, только заменив слова 'Module' на 'Special'.
Виртуальный метод AlgorithmOfModule будет тоже как надо, переопределен.

НО!! Вот загвоздка — 1) нужно то еще первое — переопределить его сигнатуру, т.е. чтобы метод принимал и возвращал объекты другого типа, пусть и унаследуемого!
2) поле лишнее entity — тоже создавать НЕ ВАРИАНТ — больше памяти будет занимать (допустим алгоритм имеет сильно упирается в память), а значит нужно переопределить
внутреннее ПОЛЕ.

Если кто понял, то подскажите, как средствами C# и .NET (а может и C++) — можно решить такую задачу "сложного многоклассового наследования" ?
Чтобы ни лишние поля в классе-обертке не создавать, и метод переопределить с унаследованной сигнатурой. Если это возможно, то целые проекты со многими
связными классами аналогично можно унаследовать, переопределив только нужную часть, а в вызывающем коде, нужно будет только заменить название-хидер проекта,
как у нас — заменяли 'Module' на 'Special'.
Какие нибудь "шаблоны проектирования" подобное позволяют?

Заранее, спасибо.