Это все о дизайне . Технически «все» вы можете сделать с недвижимостью, вы можете сделать без их, но код будет не таким изящным. Хорошая конструкция также упрощает использование классов и снижает риск ошибок.
Во-первых, ваше сравнение
TPerson = class
private
FName: string;
public
property Name: string read FName write FName;
end;
в
TPerson = class
private
FName: string;
public
procedure SetName(const Name: string);
function GetName: string;
end;
не совсем справедливо. Действительно, в первом случае у вас нет шансов делать что-то, когда значение установлено (или прочитано). Таким образом, более подходящее сравнение было бы сравнить последний код
TPerson = class
private
FName: string;
procedure SetName(const Name: string);
function GetName: string;
public
property Name: string read GetName write SetName;
end;
Например, если вы пишете контроль, часто необходимо аннулировать (в основном, перекрашивать) управления, когда вы изменяете свойство, скажем, «Цвет свитера» TPerson
.Например,
TPerson = class
private
FSweaterColor: string;
procedure SetSweaterColor(const Value: TColor);
public
property SweaterColor: TColor read FSweaterColor write SetSweaterColor;
end;
...
implementation
procedure TPerson.SetSweaterColor(const Value: TColor);
begin
if FSweaterColor <> Value then
begin
FSweaterColor := Value;
Invalidate; // causes a repaint of the control
end;
end;
Во всяком случае, в чем смысл свойств? Ну, в общем, дело в том, чтобы сделать приятный интерфейс этого класса: он должен быть прост в использовании для кого-то, не заинтересованного в деталях его реализации. Используя свойства, вы можете достичь этой цели. Действительно, чтобы прочитать текущий цвет свитера, вы просто прочитали Anna.SweaterColor
, и, чтобы установить его, вы просто Anna.SweaterColor := clRed
. Вы не знаете, просто ли это задает переменную или запускает процедуру, и вам все равно. Что касается вас, объект TPerson
просто имеет читаемое и настраиваемое свойство, называемое SweaterColor
.
Вы также можете создавать свойства, доступные только для чтения (без write
) или только для записи (нет read
). Но независимо от того, как вы реализуете свойства read
и write
(если вообще), свойство будет выглядеть одинаково с точки зрения пользователя класса. Он не должен забывать использовать SetSweaterColor
или GetSweaterColor
(на самом деле, они частные и недоступны для него), но только SweaterColor
.
Это также указывает на другое преимущество использования свойств. Публичные и опубликованные свойства видны для пользователей класса, в то время как частные члены не являются (например, поле FSweaterColor
и процедура SetSweaterColor
). Это хорошо. Потому что теперь вы знаете, что единственный способ для пользователя класса изменить цвет свитера человека - использовать свойство SweaterColor
, которое гарантирует перерисовку элемента управления. Если переменная FSweaterColor
была общедоступной, пользователь этого класса мог бы задать это и задаться вопросом: «Почему ничего не происходит, когда я меняю цвет свитера?» Конечно, вам не нужны свойства, чтобы получить это преимущество: личное поле FSweaterColor
и общественные GetSweaterColor
и SetSweaterColor
будут делать то же самое, но тогда вам нужно будет написать функцию GetSweaterColor
, даже если обработка не требуется для получения цвета , Кроме того, пользователю класса необходимо научиться использовать два идентификатора вместо одного.
Более конкретно, если вы используете программу Delphi для IDE, вы увидите, что в Инспекторе объектов отобразится published property
(-y + ies), где вам разрешено читать/изменять их (если применимо). Как это было бы возможно, если бы не свойства?
Все это говорит о том, что иногда вы не используете свойства, хотя можете. Например, если у вас есть свойство «только для чтения», вы можете перейти к единственной публичной функции GetSomething
вместо свойства «только для чтения». В конце концов, это спасет вас от некоторой кодировки. Аналогично, если у вас есть свойство только для записи, вы можете пойти с одной общедоступной процедурой SetSomething
, которая также сохранит ваш код. Наконец, если у вас есть свойство read/write, которое не требует обработки ни в одну сторону (ни для получения, ни для установки), вы можете просто использовать общедоступную переменную!
Итак, в конце концов, вам нужно выбрать хороший дизайн своего класса на основе класса. Я предполагаю, что короткая версия моего слишком длинного ответа похожа на комментарий Дэвида:
Использовать в зависимости от того, что вам больше нравится, в зависимости от того, что удобнее.
В Delphi принято использовать 'F' в качестве префикса для (частных) полей, то есть' FName'. –
Используйте то, что вам больше нравится, в зависимости от того, что удобнее. –
Я бы лично не использовал 'p' для частных полей, потому что' P' уже широко используется как тип указателя, например 'PChar'. 'F' является наиболее используемым. –