Что-то не могу понять... Хочу скрыть published/public свойство, объявленное в базовом классе. В производном классе переношу его в секцию private/protected — ничего не меняется — свойство остается доступным клиентам производного класса.
type
TBase = class
private
FMember: Integer;
public
property Member: Integer read FMember;
end;
TDerived = class(TBase)
private// protectedproperty Member;
end;
// ...var
D: TDerived;
begin
Writeln(D.Member); // Здесь хочу ошибку компиляции
Получается, что можно только "повышать" область видимости?
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Спасибо, то что надо. Жаль только, что это по прежнему оставляет возможность обращения к этому свойству в коде, ну да ладно, видно ничего не поделаешь.
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Здравствуйте, ekamaloff, Вы писали:
E>Всем привет.
E>Что-то не могу понять... Хочу скрыть published/public свойство, объявленное в базовом классе. В производном классе переношу его в секцию private/protected — ничего не меняется — свойство остается доступным клиентам производного класса.
E>Получается, что можно только "повышать" область видимости?
Ты можешь его "спрятать" объявив такое же, но пустое. Правда, до предыдущего все равно можно будет добраться через привдение типов.
... << RSDN@Home 1.2.0 alpha rev. 622>>
Re[3]: Скрыть свойство
От:
Аноним
Дата:
10.04.06 20:45
Оценка:
LT>>Вообще-то, положено именно так.
E>Плохо значит, что так положено. Глупость какая-то.
Угу, а почему в самолете стоп-крана нету? Глупость какая-то!
Ну как ты скроешь свойство, если любой класс — это и любой из его родителей?
Об этом, кстати, в справке, кажется, написано
Зачем тебе эта иллюзия непонятно чего?.
TObject -> TParent -> TChild
var Child : TChild;
(**** skip ***)procedure DoSomething(AnyObject: TParent);
begin
ShowMessage(AnyObject.MyHiddenProperty);
end;
(**** skip ***)
Child.MyHiddenProperty := '12345'; //Ошибка! Нет такого свойства
DoSomething(Child); //И всё-таки оно еcть!
ShowMessage(Child.MyHiddenProperty); // Ложку видишь? А нету её!
Здравствуйте, Denis_TST, Вы писали:
E>>Получается, что можно только "повышать" область видимости? D_T>Ты можешь его "спрятать" объявив такое же, но пустое. Правда, до предыдущего все равно можно будет добраться через привдение типов.
Не помогает это, написано же в первом сообщении.
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Здравствуйте, Аноним, Вы писали:
А>Ну как ты скроешь свойство, если любой класс — это и любой из его родителей?
<>
Если бы все в программировании было так, как кажется правильным по логике, было бы просто замечательно. Но иногда все таки нужно скрыть свойство/метод объявленные в предке — не бывает правил без исключений. В объектной модели C++ например это возможно, а в Delphi — нет.
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Здравствуйте, demiurgjr, Вы писали:
D>Перемести в private, а потомка в другой модуль.
Я привел немного неудачный пример. Про то, что в модуле можно обращаться к приватным членам любых классов, объявленных в этом же модуле я и сам знаю . Вынесение обращения в другой модуль проблемы не решает
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Здравствуйте, ekamaloff, Вы писали:
E>Здравствуйте, Аноним, Вы писали:
А>>Ну как ты скроешь свойство, если любой класс — это и любой из его родителей?
E><>
E>Если бы все в программировании было так, как кажется правильным по логике, было бы просто замечательно. Но иногда все таки нужно скрыть свойство/метод объявленные в предке — не бывает правил без исключений. В объектной модели C++ например это возможно, а в Delphi — нет.
Что то вы путаете. Нельзя в С++ занижать область видимости.
#include <iostream>
class CBase
{
public:
virtual int testFunc() = 0;
};
class CParent: public CBase
{
public:
CParent(){}
~CParent(){}
int testFunc(){return 0;}
};
class CChild: public CParent
{
private:
int testFunc(){return 1;}
public:
CChild(){}
~CChild(){}
};
int _tmain(int argc, _TCHAR* argv[])
{
CBase* p[2];
p[0] = new CParent;
p[1] = new CChild;
std::cout<<"Parent "<<p[0]->testFunc()<<"Child "<<p[1]->testFunc()<<std::endl;
return 0;
}
Посмотрите результат.
class Base
{
public:
void f() {}
};
class Child1: public Base
{
private:
using Base::f;
};
class Child2: public Base
{
};
int main()
{
Child1 c1;
Child2 c2;
c1.f(); // ошибка компиляции (этого то мне и хотелось)
c2.f(); // ОК
}
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Здравствуйте, ekamaloff, Вы писали:
E>Здравствуйте, vasmann, Вы писали:
E><>
V>>Посмотрите результат.
E>Даже смотреть не буду, я имел ввиду другое:
E>
E>class Base
E>{
E>public:
E> void f() {}
E>};
E>class Child1: public Base
E>{
E>private:
E> using Base::f;
E>};
E>class Child2: public Base
E>{
E>};
E>int main()
E>{
E> Child1 c1;
E> Child2 c2;
E> c1.f(); // ошибка компиляции (этого то мне и хотелось)
E> c2.f(); // ОК
E>}
E>
Смешно.
А зачем тогда наследование?
В чем суь этого маразма?
Здравствуйте, ekamaloff, Вы писали:
E>Здравствуйте, demiurgjr, Вы писали:
D>>Перемести в private, а потомка в другой модуль.
E>Я привел немного неудачный пример. Про то, что в модуле можно обращаться к приватным членам любых классов, объявленных в этом же модуле я и сам знаю . Вынесение обращения в другой модуль проблемы не решает
От кого порождаемся то? Может все попроще можна организовать...
Хороший стиль программирования это делать промежуточную компонету
type
TCustomSuperComponent = class (TCompoent)
protected
property Prop1 : Integer read GetProp1 write SetProp1;
public
property Prop2 : Integer read GetProp1 write SetProp2;
end;
TSuperComponent = class (TCustomSuperComponent)
published
property Prop1; // повышаем видимостьproperty Prop2;
end;
Ну и как уже говорилось выше, понизить видимость никак нельзя...
Здравствуйте, Danchik, Вы писали:
D>От кого порождаемся то? Может все попроще можна организовать...
Порождаемся от готового, написанного не мной класса (он находится в VCL ), в котором мне требуется практически вся реализованная функциональность, за исключением одного свойства (более того, оно по смыслу начинает конфликтовать с другим свойством, введенным мной в производном классе, поэтому мне для пущего порядка захотелось его скрыть). Менять класс не могу. Копировать к себе полностью не хочу. Его базовый класс слишком убог, нормальный промежуточный слой (типа TCustomBlaBlaBla) не ввели.
D>Хороший стиль программирования это делать промежуточную компонету D>
Здравствуйте, ekamaloff, Вы писали:
E>Здравствуйте, Danchik, Вы писали:
D>>От кого порождаемся то? Может все попроще можна организовать...
E>Порождаемся от готового, написанного не мной класса (он находится в VCL ), в котором мне требуется практически вся реализованная функциональность, за исключением одного свойства (более того, оно по смыслу начинает конфликтовать с другим свойством, введенным мной в производном классе, поэтому мне для пущего порядка захотелось его скрыть). Менять класс не могу. Копировать к себе полностью не хочу. Его базовый класс слишком убог, нормальный промежуточный слой (типа TCustomBlaBlaBla) не ввели.
Ну что ж...
Скрываем в инспекторе обьектов как уже обговаривалось. В порожденном делем такое же свойство но с ассершинами на доступ. И молимся чтобы к свойству не доступились через приведение типов
Здравствуйте, Danchik, Вы писали:
D>Здравствуйте, ekamaloff, Вы писали:
E>>Здравствуйте, Danchik, Вы писали:
D>>>От кого порождаемся то? Может все попроще можна организовать...
E>>Порождаемся от готового, написанного не мной класса (он находится в VCL ), в котором мне требуется практически вся реализованная функциональность, за исключением одного свойства (более того, оно по смыслу начинает конфликтовать с другим свойством, введенным мной в производном классе, поэтому мне для пущего порядка захотелось его скрыть). Менять класс не могу. Копировать к себе полностью не хочу. Его базовый класс слишком убог, нормальный промежуточный слой (типа TCustomBlaBlaBla) не ввели.
D>Ну что ж... D>Скрываем в инспекторе обьектов как уже обговаривалось. В порожденном делем такое же свойство но с ассершинами на доступ. И молимся чтобы к свойству не доступились через приведение типов
Можно и проще.
По паттерну адаптер.
Определяеш свой класс с тем же интерфейсом, как и базовый тебе нужный. Делаешь внутренний член того класса проперть которого тебе не нравится, и все запросы, кроме этой самой проперти делегируещь в тот класс, а работу с твоей пропертью делаешь отдельно. Хотя если нужно чтобы новый класс принадлежал той же иерархии что и сновной твой класс, то тогда предыдущий пост должен помоч, если нет, то этот прием будет более правильным.
Re[9]: Скрыть свойство
От:
Аноним
Дата:
11.04.06 14:10
Оценка:
Здравствуйте, vasmann, Вы писали:
[Skip]
V>Можно и проще. V>По паттерну адаптер. V>Определяеш свой класс с тем же интерфейсом, как и базовый тебе нужный. Делаешь внутренний член того класса проперть которого тебе не нравится, и все запросы, кроме этой самой проперти делегируещь в тот класс, а работу с твоей пропертью делаешь отдельно. Хотя если нужно чтобы новый класс принадлежал той же иерархии что и сновной твой класс, то тогда предыдущий пост должен помоч, если нет, то этот прием будет более правильным.
C VCL-евскими контролами, паттерн адаптер, ну никуда не лезет Разве что подход панелька, а внутри контрол. Изврат еще тот, только грабли натворим.
А вот с невизуальными.. Чесно, так бы и сделал не задумываясь
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, vasmann, Вы писали:
А>[Skip]
V>>Можно и проще. V>>По паттерну адаптер. V>>Определяеш свой класс с тем же интерфейсом, как и базовый тебе нужный. Делаешь внутренний член того класса проперть которого тебе не нравится, и все запросы, кроме этой самой проперти делегируещь в тот класс, а работу с твоей пропертью делаешь отдельно. Хотя если нужно чтобы новый класс принадлежал той же иерархии что и сновной твой класс, то тогда предыдущий пост должен помоч, если нет, то этот прием будет более правильным.
А>C VCL-евскими контролами, паттерн адаптер, ну никуда не лезет Разве что подход панелька, а внутри контрол. Изврат еще тот, только грабли натворим. А>А вот с невизуальными.. Чесно, так бы и сделал не задумываясь
Про паттерн и панельку:
Знаю что геморойно, сам такое делал, по крайней мере у нас это решилось как самое правильное и не вредящее решение. Другие мысли не понраились ибо выглядели очень косяково на фоне этой. Согласись что сделать свой класс как обертку другому намнго надежнее чем сделать его наследником попытаться перекрыть свойство (что в принципе не возможно) и потом надеяться что кто то когда то его не вызовет, по крайней мере как по мне это самый косяк — надеяться а не знать что его не вызовут. Я лучше час/два а то и день потрачу на это но зато буду знать что надеятся ни на что не надо будет, ты быдешь строго знать как себя поведет твой компонент в той или инной ситуации.
Спасибо.