Сложное (многоклассовое) наследование и полиморфизм — возможно или нет?
Когда я сталкивался ранее с наследованием классов и полиморфизмом, то это было или,
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
Что же в таком случае получается? Допустим у нас первый проект, с классами 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'.
Какие нибудь "шаблоны проектирования" подобное позволяют?