Приховати public-метод у спадкоємці

Як можна приховати public-метод у спадкоємці класу? Наприклад, TStringList має 2 методи - Add і AddObject. Як зробити невидимим для спадкоємця метод Add?

У принципі ніяк не зробиш. Бо завжди можна закастити під предка і викликати метод

А якщо без наведення типів? Наприклад:

TGetList=class(TStringList) private function Add: Integer; reintroduce; end;

В цьому випадку мета досягається, але отримуємо хінт, що метод ніде не використовується.

Звуження області видимості неможливе. Якби це було можливим, то й поліморфізму не було б.

Ладно. Дякую всім. Буду Exception видавати у разі використання.

хм. Я, напевно, трохи ввів в оману. Хотів сказати - приховати в спадкоємці від спадкоємця.

TGetList=class(TStringList) private function Add: Integer; reintroduce; public constructor Create; end;

конструктор TGetList.Create; begin Add; end;

У принципі, якщо перенести метод у private-секцію, як заглушку і використовувати при виклику, наприклад, конструктора, то хінт видаватися не буде.

Адже користувач класу очікує, що метод працює за аналогією з батьківським класом. Хотілося б виключити будь-яку помилку.

А метод у [6] не підійде?

function Add: Integer; virtual; abstract; reintroduce;

Якщо вийде, то ти матимеш новий ланцюжок успадкування і водночас абстрактний метод, який приховує метод предка.

А шкода, я так сподівався. Ну, тоді без abstract

Вибачаюсь за можливу грубість.

> У цьому випадку мета досягається, але отримуємо хінт Чи, а не пофігу на той хінт?

> В принципі, якщо перенести метод у private-секцію, як заглушку > і використовувати при виклику, наприклад, конструктора, хінт > видаватися не буде

Дався тобі цей хінт. Хінти – звичайна справа. Наприклад при будь-якому використанні PChar дельфі лається - unsafe type. У нас своя голова за плечима :)

У мене перед релізом не лишається хінтів у програмі.

Ясно, значить справа принципу і Pointer ви ніколи не використовуєте і PChar?

А як же вдається використовуючи Pointer і PChar уникати всіх hint??

const Someconst : PChar = "А ось і хінт";

type TSomerecord = Record Addr: Pointer; // А ось і другий хінт . End;

Someproc = Procedure(Addr:Pointer); // третій хінт

Можу ще привести

Саш, хінт - не проблема, його можна погасити відповідною директивою Я не зовсім зрозумію - навіщо це треба 2 Питання 1 хто користуватиметься класом - нащадком - ти чи не ти? 2. метод статичний чи віртуальний?

Якщо взяти саме цей приклад (Add, AddObject), то краще напевно зробити так: переписати метод Add в секції паблік, але додасть параметр (зробити так само, як і в AddObject) (якщо наприклад у стрінг аркуші не повинно виявитися ітем без обжектів)

Вибачте, Warning а не Hint в D7 звучить так:

1 - "Unsafe type PChar" 2 і 3 - "Unsafe type Pointer"

На жаль, я помилився - сховати метод все одно не вдалося. Це можливо тільки за умови винесення предка в інший модуль, як я зрозумів.

Користуватимуся я. Але ж не треба зарікатися-)

Ну сховати неможливо за визначенням, можна розпочати новий ланцюжок успадкування.

Все-таки так і залишилося не зрозумілим, чому саме хочеш приховати, адже цілком достатньо змінити поведінку, тільки треба враховувати й інші методи, наприклад цей метод.викликає Insert який у предка абстрактний, на відміну від Add, також є ще й ряд інших аналогічних методів.

Може, треба подумати над перепроектуванням? Щось десь не те, коли таке знадобилося.

Спадкоємець TStrinList використовується для зберігання списків об'єктів.

У спадкоємці об'єкти можна додавати лише методом AddObject(теж переписаним).

Це робиться для того, щоб список формував строго за певними правилами.

А чому саме спадкоємець від TStringList, а не TList наприклад?

Мені потрібна наявність властивості Strings.

Фактично, в Strings зберігаються ключі, якими виробляється сортування і пошук.

Анатолію, я вже зрозумів, що не вдасться приховати-) Тому піду твоїй пораді - перепишу метод з винятком.

TMasterList=class(TStringList) private // FDB: IDBInterface; //Інтерфейс для роботи з БД FNet: INetInterface; //Інтерфейс роботи з мережею FG: TGuard; //Для роботи з кількома потоками FSortDirect: Boolean; FQuantity: Integer; procedure Add; reintroduce;//Приховуємо метод procedure FreeObject(Index: Integer); procedure CheckKey(aKey: String); //Перевірка на порожній ключ function GetKeys: TStringList; функція GetForumObject(Index: String): TForumObject; procedure SetForumObject(Index: String; const Value: TForumObject); procedure Enter; procedure Leave; // procedure CheckQuantity; protected функція CompareStrings(const S1, S2: string): Integer; override; //Перекритий для методу QuickSort public constructor Create; virtual; Destructor Destroy; override;

function AddObject(aForumObject: TForumObject): Integer; reintroduce;

procedure InsertObject(Index: Integer; aForumObject: TForumObject);повторно вводити; procedure Delete(Індекс: Integer); повторно вводити; перевантаження; procedure Delete(aId: String); повторно вводити; перевантаження; procedure Delete(aObject: TForumObject); повторно вводити; перевантаження; функція IndexOf(const S: рядок): Integer; перевизначити; function Exists(aId: String): Boolean;

функція DeleteFromDB(aId: String): Boolean; віртуальний; функція SyncToDB; віртуальний; функція SyncFromDB; віртуальний; функція SetObjectFromDB; віртуальний; функція AddObjectFromDB; віртуальний; функція WriteObjectToDB; віртуальний; > Ключі властивості: TStringList читання GetKeys; властивість SortDirect: логічне читання FSortDirect запис FSortDirect; властивість ForumObject[Index: String]: TForumObject читання GetForumObject запис SetForumObject; властивість Quantity: Integer read FQuantity write FQuantity; кінець;

Ситуація понятна, сам так частенько роблю, в Strings храню UID на об'єкті, але з написанням свого класу не заморачивался.

Як варіант можна використовувати IndexOfObject, але про сортування тут звичайно річ не йде.

Взагалі звичайно універсальний варіант - наслідувати TStrings, а потрібні методи переносити Copy/Paste.

З TStringList як зручно тим, що не надо вимагати методи у свій модуль;)

Я в такому випадку зробив би по варіанту [10]. Тем більше, якщо планується подальше наращивання спадкоємців

У мові C++ можливо при визначенні класу об'явити тип наслідування. Якщо він, к прикладу, приватні, то публічні методи наступного класу в наступному становляться приватними.

> TGetList=class(TStringList) > приватний > функція Add: Integer; повторно ввести; > кінець;

А якщо не робити TGetList спадкоємцем TStringlist? А зробити типу так:

Тоді доведеться переписати методи длядоступ до SL.

Е-е-е.. так Вам шашечки чи їхати? :-) Якщо потрібно по-чесному саме приховати, то делегування, IMHO, один із найкращих варіантів. Якщо не єдиний.

Див [10]. "Все вже вкрадено до нас" (c)

Ну приховати - це ж побічне завдання, і далеко не найважливіша-) Більш пріоритетна - зручність використання класу. Тому - ну не вдалося приховати, ну і добре-)

Ще раз дякую всім за обговорення.

Не треба використовувати спадкування. Потрібно використовувати композицію. Піст [50] найбільш відповідне рішення.

Не треба плутати програмістів будь-якими reintroduce, що використовуються не за прямим призначенням :)

А чим краще? Вперше вирішив використати успадкування, а тут обламати хочеш такий намір;)

"Якщо батьківський клас у більшості випадків "підмінюватиме" свого нащадка, то використовується успадкування. Якщо ж батьківський клас потрібен лише, щоб клас-нащадок міг використовувати деякі його властивості, то найкращим вибором буде композиція.

Однією фразою: чим більше клас-нащадок схожий на батьківський клас, тим краще використовувати спадкування, а не композицію."

Спадкування має здохнути.

А як, наприклад, змінити порядок сортування в TStringList без наслідування? Та й більшість властивостей батьківського кдасу використовується за призначенням.

Разом із поліморфізмом чи окремо?

> Як, наприклад, змінити порядок сортування в TStringList > без наслідування?

> Та й більшість властивостей батьківського кдасу використовують > за призначенням.

А навіщо тоді такий геморой із прихованням методу Add?

Я ж не буду викликати після кожної операції зі списком CustomSort?

Це, загалом, бувєдине незрозуміле на той момент питання.-)

Спадкування, як воно існує у поширених мовах, занадто каламутне і перевантажене: воно одночасно і опис інтерфейсу, і реалізація інтерфейсу та реюз коду.

А ось народ пише таке:

"Спадкування є корисною концепцією програмування, але не завжди варто вдаватися до неї. Найчастіше з подібними завданнями краще справляються інтерфейси. Цей розділ і розділВипадки використання інтерфейсівдопоможуть вибрати потрібний підхід.

Спадкування краще використовувати у таких випадках.

1.Ієрархія успадкування є відносинами тотожності (is-a), а чи не відносини включення (has-a). 2.Можна повторно використовувати код із базових класів. 3. Необхідно застосувати той же клас і методи до інших типів даних. 4. Ієрархія класу містить досить мало рівнів, і інші розробники навряд чи будуть додавати до неї інші рівні. 5. Необхідно внести докорінні зміни до похідних класів шляхом зміни базового класу. "

З діалогу з директором школи, який отримав у подарунок клас ДВК - Порадьте, як нам отримати від цього максимальну користь. - Цього я не можу. Але можу порадити, як отримати від цього мінімальну шкоду.

Подивіться краще сюди: http://zonnon.ethz.ch/papers/Zonnon_Language_Report_v02r02_2_y041101.pdf

Подивився. Але не можу сказати, наскільки приживеться.

Ця, не вбивайте гілку, плиз. У мене у світлі цього обговорення також питання. Просто зараз ніколи. ;0)

Я солідарний з [10] та [50]. Я зробив би так. Якщо, звичайно, Олександру не потрібно передавати свій список кудись, де очікується інтерфейс базового класу TStringList.

А взагалі, все залежить від завдання, яке стоїть перед Олександром.У випадках, я нічого поганого в раді Анатолія (порушувати виняток) не бачу.

Якщо не помиляюся, то в плюсах можна ховати методи/конструктори/деструктори.

Це якщо треба зробити імітацію абстрактного методу або просто запобігти неправильному використанню. Але все визначається завданням, я ж подробиць не знаю.

Тут висловлювалося негативне ставлення до наслідування. Не бачу нічого в ньому поганого. ІМХО в дизайні має бути все збалансовано.

Як баланс можу навести приклад бібліотеку "свінг" в java. Вважаю, що реалізований у них підхід з використання поліформізму і спадкування дуже лаконічний.