Скрыть свойство
От: ekamaloff Великобритания  
Дата: 06.04.06 07:03
Оценка:
Всем привет.

Что-то не могу понять... Хочу скрыть published/public свойство, объявленное в базовом классе. В производном классе переношу его в секцию private/protected — ничего не меняется — свойство остается доступным клиентам производного класса.

type
    TBase = class
    private
      FMember: Integer;
    public
      property Member: Integer read FMember;
    end;

    TDerived  = class(TBase)
    private // protected
      property 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
Re: Скрыть свойство
От: Leonid Troyanovsky  
Дата: 06.04.06 07:24
Оценка:
Здравствуйте, ekamaloff, Вы писали:

E>Получается, что можно только "повышать" область видимости?


Вообще-то, положено именно так.
См. также

http://www.rsdn.ru/Forum/Message.aspx?mid=908083&only=1
Автор: Leonid Troyanovsky
Дата: 20.11.04
--
С уважением, LVT
Re[2]: Скрыть свойство
От: ekamaloff Великобритания  
Дата: 06.04.06 08:31
Оценка:
Здравствуйте, Leonid Troyanovsky, Вы писали:

LT>Вообще-то, положено именно так.


Плохо значит, что так положено. Глупость какая-то.

LT>См. также


LT>http://www.rsdn.ru/Forum/Message.aspx?mid=908083&only=1
Автор: Leonid Troyanovsky
Дата: 20.11.04


Спасибо, то что надо. Жаль только, что это по прежнему оставляет возможность обращения к этому свойству в коде, ну да ладно, видно ничего не поделаешь.
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Re: Скрыть свойство
От: Denis_TST Россия www.transsys.ru
Дата: 10.04.06 17:40
Оценка:
Здравствуйте, 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); // Ложку видишь? А нету её!


Вот такой бред тебе нужен? Не, нафиг такое!
Re[2]: Скрыть свойство
От: ekamaloff Великобритания  
Дата: 11.04.06 03:24
Оценка:
Здравствуйте, Denis_TST, Вы писали:

E>>Получается, что можно только "повышать" область видимости?

D_T>Ты можешь его "спрятать" объявив такое же, но пустое. Правда, до предыдущего все равно можно будет добраться через привдение типов.

Не помогает это, написано же в первом сообщении.
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Re[4]: Скрыть свойство
От: ekamaloff Великобритания  
Дата: 11.04.06 03:32
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Ну как ты скроешь свойство, если любой класс — это и любой из его родителей?


<>

Если бы все в программировании было так, как кажется правильным по логике, было бы просто замечательно. Но иногда все таки нужно скрыть свойство/метод объявленные в предке — не бывает правил без исключений. В объектной модели C++ например это возможно, а в Delphi — нет.
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Re[3]: Скрыть свойство
От: demiurgjr  
Дата: 11.04.06 07:43
Оценка:
Hello, ekamaloff!
You wrote on Tue, 11 Apr 2006 03:24:27 GMT:

E>>> Получается, что можно только "повышать" область видимости?


Перемести в private, а потомка в другой модуль.

With best regards, Alexander Nagumanov.
Posted via RSDN NNTP Server 2.0
Re[4]: Скрыть свойство
От: ekamaloff Великобритания  
Дата: 11.04.06 07:57
Оценка:
Здравствуйте, demiurgjr, Вы писали:

D>Перемести в private, а потомка в другой модуль.


Я привел немного неудачный пример. Про то, что в модуле можно обращаться к приватным членам любых классов, объявленных в этом же модуле я и сам знаю . Вынесение обращения в другой модуль проблемы не решает
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Re[5]: Скрыть свойство
От: vasmann  
Дата: 11.04.06 08:09
Оценка:
Здравствуйте, 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;
}
Посмотрите результат.
Re[6]: Скрыть свойство
От: ekamaloff Великобритания  
Дата: 11.04.06 08:28
Оценка:
Здравствуйте, vasmann, Вы писали:

<>

V>Посмотрите результат.


Даже смотреть не буду, я имел ввиду другое:

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
Re[7]: Скрыть свойство
От: vasmann  
Дата: 11.04.06 08:53
Оценка:
Здравствуйте, 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>


Смешно.
А зачем тогда наследование?
В чем суь этого маразма?
Re[8]: Скрыть свойство
От: vasmann  
Дата: 11.04.06 08:58
Оценка:
И к тому же
class CBase
{
public:
virtual int testFunc() = 0;
};

class CParent: public CBase
{
public:
CParent(){}
~CParent(){}
int testFunc(){return 0;}
};

class CChild: public CParent
{
private:
using CParent::testFunc;
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;
}

тут как видим ничего не скрывается по прежнему.
Re[9]: Скрыть свойство
От: Danchik Украина  
Дата: 11.04.06 09:58
Оценка:
Здравствуйте, vasmann, Вы писали:

[Skip]

Это самое... В теги форматирования слабо оборачивать?
Re[5]: Скрыть свойство
От: Danchik Украина  
Дата: 11.04.06 10:04
Оценка: 1 (1)
Здравствуйте, 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;

Ну и как уже говорилось выше, понизить видимость никак нельзя...
Re[6]: Скрыть свойство
От: ekamaloff Великобритания  
Дата: 11.04.06 10:20
Оценка:
Здравствуйте, Danchik, Вы писали:

D>От кого порождаемся то? Может все попроще можна организовать...


Порождаемся от готового, написанного не мной класса (он находится в VCL ), в котором мне требуется практически вся реализованная функциональность, за исключением одного свойства (более того, оно по смыслу начинает конфликтовать с другим свойством, введенным мной в производном классе, поэтому мне для пущего порядка захотелось его скрыть). Менять класс не могу. Копировать к себе полностью не хочу. Его базовый класс слишком убог, нормальный промежуточный слой (типа TCustomBlaBlaBla) не ввели.

D>Хороший стиль программирования это делать промежуточную компонету

D>
D>type
D>  TCustomSuperComponent = class (TCompoent)
D>  protected
D>    property Prop1 : Integer read GetProp1 write SetProp1;
D>  public
D>    property Prop2 : Integer read GetProp1 write SetProp2;
D>  end;

D>  TSuperComponent = class (TCustomSuperComponent)
D>  published
D>    property Prop1; // повышаем видимость
D>    property Prop2;
D>  end; 
D>

D>Ну и как уже говорилось выше, понизить видимость никак нельзя...

Да, думаю, что в другой ситуации это было бы самым правильным решением.
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Re[7]: Скрыть свойство
От: Danchik Украина  
Дата: 11.04.06 10:36
Оценка: 1 (1)
Здравствуйте, ekamaloff, Вы писали:

E>Здравствуйте, Danchik, Вы писали:


D>>От кого порождаемся то? Может все попроще можна организовать...


E>Порождаемся от готового, написанного не мной класса (он находится в VCL ), в котором мне требуется практически вся реализованная функциональность, за исключением одного свойства (более того, оно по смыслу начинает конфликтовать с другим свойством, введенным мной в производном классе, поэтому мне для пущего порядка захотелось его скрыть). Менять класс не могу. Копировать к себе полностью не хочу. Его базовый класс слишком убог, нормальный промежуточный слой (типа TCustomBlaBlaBla) не ввели.


Ну что ж...
Скрываем в инспекторе обьектов как уже обговаривалось. В порожденном делем такое же свойство но с ассершинами на доступ. И молимся чтобы к свойству не доступились через приведение типов
Re[8]: Скрыть свойство
От: vasmann  
Дата: 11.04.06 10:45
Оценка: 1 (1)
Здравствуйте, 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-евскими контролами, паттерн адаптер, ну никуда не лезет Разве что подход панелька, а внутри контрол. Изврат еще тот, только грабли натворим.
А вот с невизуальными.. Чесно, так бы и сделал не задумываясь
Re[10]: Скрыть свойство
От: vasmann  
Дата: 11.04.06 15:44
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, vasmann, Вы писали:


А>[Skip]


V>>Можно и проще.

V>>По паттерну адаптер.
V>>Определяеш свой класс с тем же интерфейсом, как и базовый тебе нужный. Делаешь внутренний член того класса проперть которого тебе не нравится, и все запросы, кроме этой самой проперти делегируещь в тот класс, а работу с твоей пропертью делаешь отдельно. Хотя если нужно чтобы новый класс принадлежал той же иерархии что и сновной твой класс, то тогда предыдущий пост должен помоч, если нет, то этот прием будет более правильным.

А>C VCL-евскими контролами, паттерн адаптер, ну никуда не лезет Разве что подход панелька, а внутри контрол. Изврат еще тот, только грабли натворим.

А>А вот с невизуальными.. Чесно, так бы и сделал не задумываясь
Про паттерн и панельку:
Знаю что геморойно, сам такое делал, по крайней мере у нас это решилось как самое правильное и не вредящее решение. Другие мысли не понраились ибо выглядели очень косяково на фоне этой. Согласись что сделать свой класс как обертку другому намнго надежнее чем сделать его наследником попытаться перекрыть свойство (что в принципе не возможно) и потом надеяться что кто то когда то его не вызовет, по крайней мере как по мне это самый косяк — надеяться а не знать что его не вызовут. Я лучше час/два а то и день потрачу на это но зато буду знать что надеятся ни на что не надо будет, ты быдешь строго знать как себя поведет твой компонент в той или инной ситуации.
Спасибо.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.