Не знаю, может уже было.
Пришла вот такая мысль об ООП и наследовании:
А что, если бы была возможность при наследовании не только получать тип, унаследовавший все "богатства" от родителя, но и использовать наследники как самодостаточный тип (или тип, нормально унаследованный от ... от самодостаточного типа).
Например:
class A { int x; }
class B : A { int y; }
class C : B { int z; }
//...
// Типы *A*B содержbт все, что унаследовал от A,
// а *A*C - все от A и B
// Т.е. можно было бы записать и просто так:
// B binstance;
// C binstance;*A*B binstance;
*A*C binstance;
// Здесь звездочками окружена граница.
// Т.е. объявлена переменная типа "самодостаточный B",
// не содержащая ничего от родителя (A)*B*B binstance;
// В звездочках уже другая граница - такой тип содержит
// все, что унаследовано от B, но не от A*B*С сinstance;
Конечно, можно усомниться в ценности всего этого, но если рассмотреть практический пример:
Пусть есть MDI-приложение. Каждая дочерняя форма (MDI-child) содержит какие-то данные, которые должны быть отображены, например, в TreeView. Но этот TreeView — один на всех, т.е. при активации каждой формы, в дереве должны быть отображены только ее данные.
Конечно, можно просто хранить данные в любом формате в каждой дочерней форме и при активации заполнять ими дерево. Но если пользователь, работая с одной формой, переключился на другую, а затем — обратно, то вся навигация по деревы(например, раскрытые ноды) пропадет.
Можно еще хранить дерево (TreeView) на каждой дочерней форме целиком. Но здесь уже можно наткнуться на проблемы посерьезнее.
Но можно хранить на дочерних формах просто что-то типа *TreeView*TreeView. Таким образом сам контрол, принадлежащий MDI-паренту всегда остается на месте, он меняется лишь как TreeView. Примерно так:
class MainForm
{
TreeView dataTreeView;
void OnMdiChildActivate(...)
{
// Здесь двумя звездочками обозначено "выделение"
// из дерева типа TreeView (т.е. *Control*TreeView)
// части, принадлежащей только дереву (т.е.
// эта часть будет типа *TreeView*TreeView)
// ActiveMdiChild.DataTree - тоже типа *TreeView*TreeView
dataTreeView**TreeView = ActiveMdiChild.DataTree;
}
}
И еще к примеру: о событиях. На события дерева как Control'а подписывается только парент-форма (да и зачем это чилдренам). На события же дерева как TreeView, подписывются чилдрены (естественно, каждый — на события своего дерева). Всо ИМХО довольно красиво.
11.05.06 21:05: Перенесено из 'Архитектура программного обеспечения'
Здравствуйте, Badenweiler, Вы писали:
B>Не знаю, может уже было. B>Пришла вот такая мысль об ООП и наследовании:
B>А что, если бы была возможность при наследовании не только получать тип, унаследовавший все "богатства" от родителя, но и использовать наследники как самодостаточный тип (или тип, нормально унаследованный от ... от самодостаточного типа).
что то не понял, что понимается под самодостаточностью?
Здравствуйте, Adopt, Вы писали:
B>>Не знаю, может уже было. B>>Пришла вот такая мысль об ООП и наследовании:
B>>А что, если бы была возможность при наследовании не только получать тип, унаследовавший все "богатства" от родителя, но и использовать наследники как самодостаточный тип (или тип, нормально унаследованный от ... от самодостаточного типа). A>что то не понял, что понимается под самодостаточностью?
Разве по примерам не понятно?
Здравствуйте, Badenweiler, Вы писали:
B>>>А что, если бы была возможность при наследовании не только получать тип, унаследовавший все "богатства" от родителя, но и использовать наследники как самодостаточный тип (или тип, нормально унаследованный от ... от самодостаточного типа). A>>что то не понял, что понимается под самодостаточностью? B>Разве по примерам не понятно?
Не, как-то все очень мутно описано.
А чем простое приведение наследника к базовому типу не подходит ?
Здравствуйте, _Obelisk_, Вы писали:
_O_>А чем простое приведение наследника к базовому типу не подходит ?
Да я не об этом. Я об использовании класса-наследника не только как собственно наследника (содержащего все унаследованное), но и как самостоятельный класс.
Здравствуйте, Badenweiler, Вы писали:
B>Да я не об этом. Я об использовании класса-наследника не только как собственно наследника (содержащего все унаследованное), но и как самостоятельный класс.
По-моему вы хотите всех запутать. Если речь идет о классах, тогда используйте множественное наследование (если уж вы решили так заморочиться...)). Но речь, если я все правильно понял, идет об экземплярах класса, а следовательно вы хотите не "самодостатьчные" классы, а самодостатьчные части экземпляра класса. Но эти части тоже ведь должны иметь какой-то интерфейс... Получается что должны быть классы, описывающие их. Отсюда вывод: не морочте людям голову — используйте разные объекты разных классов (возможно дружных) + агрегация.
Здравствуйте, ZevS, Вы писали:
ZS>Но речь, если я все правильно понял, идет об экземплярах класса, а следовательно вы хотите не "самодостатьчные" классы, а самодостатьчные части экземпляра класса.
Вот-вот, ну кто-то меня понял. Пусть и с критикой
ZS>Но эти части тоже ведь должны иметь какой-то интерфейс... Получается что должны быть классы, описывающие их.
А если это будет делаться автоматом? Динамически (макросы Nemerle?)
ZS>Отсюда вывод: не морочте людям голову — используйте разные объекты разных классов (возможно дружных) + агрегация.
...
ZS>>Но эти части тоже ведь должны иметь какой-то интерфейс... Получается что должны быть классы, описывающие их. B>А если это будет делаться автоматом? Динамически (макросы Nemerle?)
На мой взгляд — это излишнее усложнение. Несоблюдение принципа "один класс — одна задача" может привести к такой запутанности кода проекта, что потом ни какой гуру не разгребет.