Свойства объектов, Property - как это и зачем это?

Форум для изучающих FPC и их учителей.

Модератор: Модераторы

Свойства объектов, Property - как это и зачем это?

Сообщение Dobrohot » 19.08.2009 19:17:46

Начал изучать объектно-ориентированное програмирование в FreePascal
Надо решить задачку "Исключить из связанного списка все элементы между двумя элементами с заданными значениями информационных полей", используя при этом свойства классов, property
Я конечно не прошу решить задачу за меня (хотя было бы неплохо :) ), просто хочу, чтобы мне популярно объяснили, как пользоваться этими свойствами, и зачем они нужны вообще...
Желательно с примерами...
(смотрел несколько самоучителей, но ничего толкового по этому поводу не нашёл...)
Dobrohot
незнакомец
 
Сообщения: 1
Зарегистрирован: 19.08.2009 18:57:10

Re: Свойства объектов, Property - как это и зачем это?

Сообщение Inferno » 20.08.2009 06:27:40

как бы проще то сказать: свойство это ну что ли "точка" через которую из/в экземпляр класса читать/писать
н-р:
Код: Выделить всё
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... это другой вопрос. Контролируют значение которое присваивается... меняют другие свойства, поля,.... это зависит от вас. Есть еще индексные свойства, и еще небольшая кучка модификаторов к ним... ищите в интернете
Аватара пользователя
Inferno
новенький
 
Сообщения: 78
Зарегистрирован: 20.03.2009 14:40:20
Откуда: Тюмень

Re: Свойства объектов, Property - как это и зачем это?

Сообщение Climber » 20.08.2009 09:32:12

Есть такая концепция - "отделение реализации от интерфейса". Интерфейс - это то, с чем работает пользователь, реализация - то, как это работает. Например, в автомобиле: пользователь жмет педаль, в двигатель подается больше топлива, автомобиль едет быстрее. В самолете пилот не жмет педаль, а тянет ручку, но эффект тот же - ускорение. В данном случае педаль и ручка - это свойства (интерфейсы), а системы подачи топлива - это реализации (методы 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 еще вызываются обработчики событий - специальные процедуры, оповещающие пользователя об изменениях.

Вот так в общих чертах это и работает.
Climber
постоялец
 
Сообщения: 415
Зарегистрирован: 03.06.2007 20:09:57
Откуда: Москва

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
Есть только одна проблемка: для всего описанного свойства вообще не нужны. Можно обойтись обычными методами.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Свойства объектов, Property - как это и зачем это?

Сообщение Climber » 26.08.2009 14:00:57

Дож писал(а):Climber
Есть только одна проблемка: для всего описанного свойства вообще не нужны. Можно обойтись обычными методами.

Я бы назвал это не проблемой, а фичей. Например, четыре логические операции (or, and, not, xor) присутствуют во всех языках, однако они избыточны и их можно свести к двум. Но никто не называет это проблемой. Так и свойства - можно без них, но с ними удобнее.
Climber
постоялец
 
Сообщения: 415
Зарегистрирован: 03.06.2007 20:09:57
Откуда: Москва

Re: Свойства объектов, Property - как это и зачем это?

Сообщение Timid » 27.08.2009 11:00:03

Climber
Неправда ваша, это не "просто фича", а крайне полезная особенность правильной реализации класса.

Например, если вы реализуете визуальный класс (LCL), то пропы будут доступны в редакторе свойств объекта. И можно установить им default значения.

Еще, метод чтения и записи будет иметь одно имя - имя свойства

Если вы хотите сделать новую реализацию методов чтения/записи, то для тестирования просто исправляется в описании класса.

Далее, свойство может являться ссылкой-методом, как обработчик события. Его можно заменять своей функцией.

Ну и так далее...
Timid
постоялец
 
Сообщения: 290
Зарегистрирован: 21.11.2007 21:33:15

Re: Свойства объектов, Property - как это и зачем это?

Сообщение Climber » 27.08.2009 11:17:20

Timid А фича - это и есть полезная особенность чего-либо (по определению).
С первыми двумя пунктами полностью согласен, с 3 и 4 наверняка поспорил бы, если бы знал все тонкости реализации аналогичных вещей в других языках.
Climber
постоялец
 
Сообщения: 415
Зарегистрирован: 03.06.2007 20:09:57
Откуда: Москва

Re: Свойства объектов, Property - как это и зачем это?

Сообщение Timid » 27.08.2009 19:32:12

Climber, я налегал на слово "просто" ;)

Насчет других языков, все не так красиво.
Но во многих скриптовых языках, к примеру, есть возможность делать Хэши - псевдомассивы с текстовыми ключами. Причем вложенные.
Паскальный подход к свойствам позволяет делать такой же код за счет свойств, имеющих типы классов.
Например, TMemo имеет свойство Lines:TStrings
TMemo.Lines.Strings['значение1']:=....
И так далее...
Timid
постоялец
 
Сообщения: 290
Зарегистрирован: 21.11.2007 21:33:15

Re: Свойства объектов, Property - как это и зачем это?

Сообщение Дож » 27.08.2009 21:19:01

Я бы назвал это не проблемой, а фичей. Например, четыре логические операции (or, and, not, xor) присутствуют во всех языках, однако они избыточны и их можно свести к двум. Но никто не называет это проблемой. Так и свойства - можно без них, но с ними удобнее.

Ключевое слово удобнее. Ваш первоначальный пост говорил о том, что property решает какую-то архитектурную проблему, а на самом деле нужен исключительно для удобства.

ПС
Можно обойтись и одной логической операцией.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Свойства объектов, Property - как это и зачем это?

Сообщение v-t-l » 28.08.2009 12:41:19

Дож писал(а):Ключевое слово удобнее. Ваш первоначальный пост говорил о том, что property решает какую-то архитектурную проблему, а на самом деле нужен исключительно для удобства.

Все языки программирования нужны "исключительно для удобства", а так - можно писать в машинных кодах :D .
v-t-l
энтузиаст
 
Сообщения: 733
Зарегистрирован: 13.05.2007 16:27:22
Откуда: Belarus

Re: Свойства объектов, Property - как это и зачем это?

Сообщение Дож » 28.08.2009 17:47:47

Все языки программирования нужны "исключительно для удобства", а так - можно писать в машинных кодах :D .

А если я назову кого-то эгоистом - то вы многозначительно ответите "Абсолютно все люди эгоисты"?

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

настолько же странным, насколько
Если вы пишите арифметику с матрицами (сложение, умножение), то operator - самое подходящее для этого средство

или
Если вы пишите список, то дженерик - самое подходящее для этого средство
.

Если вы не считаете последние два утверждения странными, то извините за беспокойство, у меня кривой внутренний мир :)

ПС
Brainfuck по-вашему тоже нужен "исключительно для удобства"? :D
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Свойства объектов, Property - как это и зачем это?

Сообщение Climber » 31.08.2009 09:09:52

Дож писал(а): Считаю утверждение
Если вдруг возникнет необходимость изменить реализацию (не ехать, а лететь), не меняя интерфейса, то свойства - самое подходящее для этого средство

настолько же странным ...

А какое же средство паскаля подходит для этого лучше, позвольте спросить?

Дож писал(а):... настолько же странным, насколько
Если вы пишите арифметику с матрицами (сложение, умножение), то operator - самое подходящее для этого средство


Operator - это в данном случае имеется ввиду перегрузка операторов сложения и умножения? Опять же, а что лучше для матриц в данном случае?

Дож писал(а):Brainfuck по-вашему тоже нужен "исключительно для удобства"? :D

Опять же, смотря какую цель вы преследуете. Если ваша цель совпадает с названием этого языка, то да, тут он лучший. :wink:
Climber
постоялец
 
Сообщения: 415
Зарегистрирован: 03.06.2007 20:09:57
Откуда: Москва

Re: Свойства объектов, Property - как это и зачем это?

Сообщение Vadim » 31.08.2009 11:06:56

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

Brainfuck это как раз то, что надо, когда случается бессонница. :)
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Свойства объектов, Property - как это и зачем это?

Сообщение Дож » 31.08.2009 15:36:21

А какое же средство паскаля подходит для этого лучше, позвольте спросить?

Я уже писал: private-поля, public-методы.

Operator - это в данном случае имеется ввиду перегрузка операторов сложения и умножения?

Да, речь идет о перегрузке.

Опять же, а что лучше для матриц в данном случае?

Оператор присваивания, сложение и умножение чисел с плавающей точкой, цикл.


Приведу совсем отстраненный пример, но считаю его аналогом:

Если вы хотите сделать шоколадную конфету, то красивый фантик - лучшее для этого средство.

Уже чувствую вопрос: а как же без фантика-то, какое же средство использовать для этого лучше?
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47


Вернуться в Обучение Free Pascal

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 15

Рейтинг@Mail.ru