Страница 1 из 1
Свойства объектов, Property - как это и зачем это?
Добавлено: 19.08.2009 19:17:46
Dobrohot
Начал изучать объектно-ориентированное програмирование в FreePascal
Надо решить задачку "Исключить из связанного списка все элементы между двумя элементами с заданными значениями информационных полей", используя при этом свойства классов, property
Я конечно не прошу решить задачу за меня (хотя было бы неплохо

), просто хочу, чтобы мне популярно объяснили, как пользоваться этими свойствами, и зачем они нужны вообще...
Желательно с примерами...
(смотрел несколько самоучителей, но ничего толкового по этому поводу не нашёл...)
Re: Свойства объектов, Property - как это и зачем это?
Добавлено: 20.08.2009 06:27:40
Inferno
как бы проще то сказать: свойство это ну что ли "точка" через которую из/в экземпляр класса читать/писать
н-р:
Код: Выделить всё
Type
TMyClass=class
private
FProp : integer;
procedure SetProp(const Value:integer);
function GetProp:integer;
public
property Prop:integer read FProp write FProp;
property Prop1:integer read GetProp write SetProp;
end;
....
prop:=10; // здесь посути присвоение идет поля класса MyClass.FProp
prop:=prop1; // по сути вызывается MyClass.FProp:= MyClass.GetProp
prop1 := 2; // вызывается MyClass.SetProp(2)
Что делают SetProp, GetProp класса TMyClass... это другой вопрос. Контролируют значение которое присваивается... меняют другие свойства, поля,.... это зависит от вас. Есть еще индексные свойства, и еще небольшая кучка модификаторов к ним... ищите в интернете
Re: Свойства объектов, Property - как это и зачем это?
Добавлено: 20.08.2009 09:32:12
Climber
Есть такая концепция - "отделение реализации от интерфейса". Интерфейс - это то, с чем работает пользователь, реализация - то,
как это работает. Например, в автомобиле: пользователь жмет педаль, в двигатель подается больше топлива, автомобиль едет быстрее. В самолете пилот не жмет педаль, а тянет ручку, но эффект тот же - ускорение. В данном случае педаль и ручка - это свойства (интерфейсы), а системы подачи топлива - это реализации (методы SetProp). В принципе, ничто не мешает переставить педаль газа в самолет, и тогда пользователь, привыкший к одному способу управления, будет переучиваться быстрее и не заметит изменения реализации. Понятно, что в реальности замена пилота водителем автомобиля чревата последствиями, но если абстрагироваться от этих деталей, мы увидим следущее: есть цепочка интерфейс (педаль) - реализация (двигатель) - результат (ускорение). Если вдруг возникнет необходимость изменить реализацию (не ехать, а лететь), не меняя интерфейса, то свойства - самое подходящее для этого средство. Например:
Код: Выделить всё
interface
TCar = class // Это машина
private
FKoef: integer;
FPedal: integer;
FSpeed: integer;
protected
procedure SetPedal(const AValue: integer); virtual; // реализация. virtual означает, что потомки класса могут изменять эту реализацию, а могут и не изменять
published
property Pedal: integer read FPedal write SetPedal; // Положение педали
property Speed: integer read FSpeed; //Скорость. Пользователь не может менять ее напрямую
property Koef: integer read FKoef; // Коэффициент ускорения, выражающий зависимость скорости от положения педали. Задается конструкцией автомобиля, то есть в конструкторе ;)
constructor Create; // Тут выделяется память и задаются всякие конструктивные особенности
end;
{ TPlane }
TPlane = class (TCar)
private
FFlyingHeight: integer; //В этих переменных все и хранится
FFlyingSpeed: integer;
FHeightKoef: integer;
protected
procedure SetPedal(const AValue: integer); override; // меняем реализацию педали, не меняя самой педали
published
property FlyingSpeed: integer read FFlyingHeight;
property HeightKoef: integer read FHeightKoef; // У самолета в конструкции заложена еще и зависимость высоты полета от скорости
end;
implementation
{ Tcar }
// Собственно реализация
procedure TCar.SetPedal(const AValue: integer); // AValue - новое значение
begin
if FPedal=AValue then exit; // если ничего не меняется - на выход
FPedal:=AValue; // Сохраняем новое значение
FSpeed:=FPedal*FKoef; //Задаем скорость
end;
{ TPlane }
// реализация самолета
procedure TPlane.SetPedal(const AValue: integer);
begin
// Поскольку скорость и педаль никуда не делись, вызываем унаследованный метод их задания (кстати, у самолета будет другой коэффициент ускорения, который должен быть задан в конструкторе - унаследованный метод это учтет):
inherited SetPedal(AValue);
// Но у самолета добавилась высота - изменяем ее:
FFlyingHeight:=FPedal*FHeightKoef;
end;
Такая реализация гарантирует, что значение положения педали и соответствующей скорости движения всегда взаимосвязаны - прямо как в настоящей машине.
В VCL в методах типа SetProterty еще вызываются обработчики событий - специальные процедуры, оповещающие пользователя об изменениях.
Вот так в общих чертах это и работает.
Re: Свойства объектов, Property - как это и зачем это?
Добавлено: 26.08.2009 10:42:01
Дож
Dobrohot
1. Извне работа со свойствами такая же, как и с полями: Obj.Prop := 5; I := Obj.Prop;
2. Свойство может иметь read-часть (I := Obj.Prop) и write-часть (Obj.Prop := 5) - если какой-то из этих частей нет, то значит, что соответстующее действие с свойством невозможно.
3. Постейший случай - свойство над переменной: property Number: Integer read FNumber write FNumber; - все действия с Number будут перенаправляться в FNumber.
4. Кроме того запись и/или чтение можно осуществлять функциями: property Number: Integer read GetNumber write SetNumber; (где function GetNumber: Integer; и procedure SetNumber(NewNumber: Integer)).
5. Есть свойства-массивы: property Items[Index: String]: TItem read GetItem write SetItem; (где function GetItem(Index: String): TItem; и procedure SetItem(Index: String; NewItem: TItem)) Обращаемся к таким полям так: Obj.Items['hello!']
6. Наконец, свойство-массив может быть объявлено с директивой default, тогда обращаться к нему можно будет при помощи Obj['hello!']
Climber
Есть только одна проблемка: для всего описанного свойства вообще не нужны. Можно обойтись обычными методами.
Re: Свойства объектов, Property - как это и зачем это?
Добавлено: 26.08.2009 14:00:57
Climber
Дож писал(а):Climber
Есть только одна проблемка: для всего описанного свойства вообще не нужны. Можно обойтись обычными методами.
Я бы назвал это не проблемой, а фичей. Например, четыре логические операции (or, and, not, xor) присутствуют во всех языках, однако они избыточны и их можно свести к двум. Но никто не называет это проблемой. Так и свойства - можно без них, но с ними удобнее.
Re: Свойства объектов, Property - как это и зачем это?
Добавлено: 27.08.2009 11:00:03
Timid
Climber
Неправда ваша, это не "просто фича", а крайне полезная особенность правильной реализации класса.
Например, если вы реализуете визуальный класс (LCL), то пропы будут доступны в редакторе свойств объекта. И можно установить им default значения.
Еще, метод чтения и записи будет иметь одно имя - имя свойства
Если вы хотите сделать новую реализацию методов чтения/записи, то для тестирования просто исправляется в описании класса.
Далее, свойство может являться ссылкой-методом, как обработчик события. Его можно заменять своей функцией.
Ну и так далее...
Re: Свойства объектов, Property - как это и зачем это?
Добавлено: 27.08.2009 11:17:20
Climber
Timid А фича - это и есть полезная особенность чего-либо (по определению).
С первыми двумя пунктами полностью согласен, с 3 и 4 наверняка поспорил бы, если бы знал все тонкости реализации аналогичных вещей в других языках.
Re: Свойства объектов, Property - как это и зачем это?
Добавлено: 27.08.2009 19:32:12
Timid
Climber, я налегал на слово "просто"

Насчет других языков, все не так красиво.
Но во многих скриптовых языках, к примеру, есть возможность делать Хэши - псевдомассивы с текстовыми ключами. Причем вложенные.
Паскальный подход к свойствам позволяет делать такой же код за счет свойств, имеющих типы классов.
Например, TMemo имеет свойство Lines:TStrings
TMemo.Lines.Strings['значение1']:=....
И так далее...
Re: Свойства объектов, Property - как это и зачем это?
Добавлено: 27.08.2009 21:19:01
Дож
Я бы назвал это не проблемой, а фичей. Например, четыре логические операции (or, and, not, xor) присутствуют во всех языках, однако они избыточны и их можно свести к двум. Но никто не называет это проблемой. Так и свойства - можно без них, но с ними удобнее.
Ключевое слово удобнее.
Ваш первоначальный пост говорил о том, что property решает какую-то архитектурную проблему, а на самом деле нужен исключительно для удобства.
ПС
Можно обойтись и одной логической операцией.
Re: Свойства объектов, Property - как это и зачем это?
Добавлено: 28.08.2009 12:41:19
v-t-l
Дож писал(а):Ключевое слово удобнее. Ваш первоначальный пост говорил о том, что property решает какую-то архитектурную проблему, а на самом деле нужен исключительно для удобства.
Все языки программирования нужны "исключительно для удобства", а так - можно писать в машинных кодах

.
Re: Свойства объектов, Property - как это и зачем это?
Добавлено: 28.08.2009 17:47:47
Дож
Все языки программирования нужны "исключительно для удобства", а так - можно писать в машинных кодах

.
А если я назову кого-то эгоистом - то вы многозначительно ответите "Абсолютно все люди эгоисты"?
Видимо, вы меня не совсем правильно поняли. С учетом контекста, я утверждаю "Property лишь упрощают воплощение концепции отделения реализации от интерфейса (эта концепция воплощается public-методами с private-полями), но ничего нового в архитектуру кода внести не могут." Считаю утверждение
Если вдруг возникнет необходимость изменить реализацию (не ехать, а лететь), не меняя интерфейса, то свойства - самое подходящее для этого средство
настолько же странным, насколько
Если вы пишите арифметику с матрицами (сложение, умножение), то operator - самое подходящее для этого средство
или
Если вы пишите список, то дженерик - самое подходящее для этого средство
.
Если вы не считаете последние два утверждения странными, то извините за беспокойство, у меня кривой внутренний мир

ПС
Brainfuck по-вашему тоже нужен "исключительно для удобства"?

Re: Свойства объектов, Property - как это и зачем это?
Добавлено: 31.08.2009 09:09:52
Climber
Дож писал(а): Считаю утверждение
Если вдруг возникнет необходимость изменить реализацию (не ехать, а лететь), не меняя интерфейса, то свойства - самое подходящее для этого средство
настолько же странным ...
А какое же средство паскаля подходит для этого лучше, позвольте спросить?
Дож писал(а):... настолько же странным, насколько
Если вы пишите арифметику с матрицами (сложение, умножение), то operator - самое подходящее для этого средство
Operator - это в данном случае имеется ввиду перегрузка операторов сложения и умножения? Опять же, а что лучше для матриц в данном случае?
Дож писал(а):Brainfuck по-вашему тоже нужен "исключительно для удобства"?

Опять же, смотря какую цель вы преследуете. Если ваша цель совпадает с названием этого языка, то да, тут он лучший.

Re: Свойства объектов, Property - как это и зачем это?
Добавлено: 31.08.2009 11:06:56
Vadim
Дож писал(а):Brainfuck по-вашему тоже нужен "исключительно для удобства"?
Brainfuck это как раз то, что надо, когда случается бессонница.

Re: Свойства объектов, Property - как это и зачем это?
Добавлено: 31.08.2009 15:36:21
Дож
А какое же средство паскаля подходит для этого лучше, позвольте спросить?
Я уже писал: private-поля, public-методы.
Operator - это в данном случае имеется ввиду перегрузка операторов сложения и умножения?
Да, речь идет о перегрузке.
Опять же, а что лучше для матриц в данном случае?
Оператор присваивания, сложение и умножение чисел с плавающей точкой, цикл.
Приведу совсем отстраненный пример, но считаю его аналогом:
Если вы хотите сделать шоколадную конфету, то красивый фантик - лучшее для этого средство.
Уже чувствую вопрос: а как же без фантика-то, какое же средство использовать для этого лучше?