2012-02-22 1 views
7

В одном базовом классе есть защищенный метод. При наследовании этого класса я хочу скрыть эту процедуру от использования извне. Я попробовал переопределить его в пределах частных и даже строгих частных секций, но его все еще можно вызвать извне. Класс Original не мой, поэтому я не могу изменить способ определения TOriginal.Как скрыть защищенную процедуру объекта?

Можно ли скрыть эту процедуру в моем унаследованном классе? И как?

type 
    TOriginal = class(TObject) 
    protected 
    procedure SomeProc; 
    end; 

    TNew = class(TOriginal) 
    strict private 
    procedure SomeProc; override; 
    end; 
+2

, если вы хотите, чтобы скрыть метод базового класса из потомка класса, то вы должны объявить его в частный раздел; частные методы видны только из класса self; защищенные методы видны из класса itslef и унаследованных классов , и, наконец, общедоступные или опубликованные методы видны для всех; опубликованный аналогичен публичному, но эти разделы используются средой delphi для создания свойств компонентов, видимых в инспекторе объектов; – teran

+0

также есть два термина «сокрытие» и «переопределение»; в вашем примере вы должны пометить 'SameProc' в базовом классе как' virtual'; и затем вы обновляете его в унаследованном классе и отмечаете его как 'override', это означает переопределение; это означает, что если вы создаете «TNew» и присваиваете свой экземпляр переменной «TOriginal» («var orig: = TNew.Create()»), и после этого вызова orig.SomeProc будет вызываться реализация TNew.SomeProc; , если вы не отметите его как 'override', то orig.SomeProc равно' TOriginal.SomeProc' также бесполезно понижать видимость метода, потому что вы всегда можете его повышать и вызывать – teran

+2

. Что останавливает код, используя ваш производный класс от ссылок на ссылки ссылки на базовые классы или их назначение? Получение доступа к любым «скрытым» методам? То, что вы хотите, не может быть сделано. Если вы чувствуете желание сделать это, то отношения наследования ошибочны. – mghie

ответ

11

Защищенные методы уже скрыты от внешней стороны. (В основном, см. Ниже.) Вы не можете уменьшить видимость члена класса. Если базовый класс объявил метод защищенным, то все потомки этого класса могут использовать этот метод.


В Delphi, другой код в той же единице, как класс, может получить доступ к защищенным членам данного класса и даже код из несвязанных классов. Иногда это может быть полезно, но обычно для работы с другими недостатками дизайна. Если у вас есть что-то, что «действительно, действительно» должно быть защищено, вы можете сделать его строгим, а затем специальное правило доступа одного и того же устройства не применяется.

+0

И используя «помощников класса», по-прежнему можно получить доступ к строгим защищенным/закрытым членам. –

+0

@LURD, если нет «помощников блока», нет возможности доступа к закрытым членам. – OnTheFly

+0

Исходный класс ('TOriginal') не мой класс, поэтому я не могу его просто изменить. Глядя дальше в исходный класс, я вижу, что 'SomeProc' на самом деле * public * дальше в семье, но этот класс, который я наследую, переместил его в' protected', что объясняет, почему я могу получить к нему доступ тогда , Итак, как только что-то было открыто, оно не может быть разоблачено? –

1

После того, как подвергается вы не можете скрыть это, но вы можете сделать это на месте, где его называют предельным образом

TOriginalClass = class 
public 
    procedure Foo; 
end; 

TNewClass = class(TOriginalClass) 
public 
    procedure Foo; reintroduce; 
end; 

implementation 

procedure TNewClass.Foo; 
begin 
    Assert(False, 'Do not call Foo from this class'); 
    inherited Foo; 
end; 

var Obj: TNewClass; 
Obj := TNewClass.Create; 
Obj.Foo; // get assert message 

Will not get Assert error if declared as TOriginalClass 
var Obj: TOriginalClass; 
Obj := TNewClass.Create; 
Obj.Foo; // Never get the assert message 
+0

Спасибо за ответ, и я немного понимаю, но я не понимаю, откуда синтаксис C-like ... Это не похоже на чистый код Delphi ... –

+0

Хотя я понимаю суть, код по-прежнему немного подозрительный, в основном оба класса имеют «Foo' in * public *? –