Не знаю, может уже было.
Пришла вот такая мысль об ООП и наследовании:
А что, если бы была возможность при наследовании не только получать тип, унаследовавший все "богатства" от родителя, но и использовать наследники как самодостаточный тип (или тип, нормально унаследованный от ... от самодостаточного типа).
Например:
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: Перенесено из 'Архитектура программного обеспечения'