Уласьцівасьць (праграмаваньне)
У пэўных аб’ектна-арыентаваных мовах праграмаваньня уласьцівасьць — асаблівы від члена клясы, які зьяўляецца сярэднім паміж палямі дадзеных і мэтадамі. Звычайна запіс і чытаньне ўласьцівасьці ажыцьцяўляецца як запіс і чытаньне поля, але звычайна гэта трансьлюецца ў выклікі мэтадаў для запісу і чытаньня. Сынтаксіс з выкарыстаньнем палёў дадзеных зьяўляецца прасьцейшым для ўспрыманьня і напісаньня, чым стварэньне вялікай колькасьці выклікаў мэтадаў, але выкарыстаньне мэтадаў у такіх выпадках дазваляе ажыцьцяўляць праверку зьвестак на карэктнасьць, актыўнае абнаўленьне (напрыклад, аб’ектаў інтэрфэйсу карыстальніка), і/або запіс у палі, прызначаныя толькі для чытаньня. Таму ўласьцівасьці зьяўляюцца прамежкавым этапам паміж кодам і дадзенымі экзэмпляраў клясы. Апроч гэтага ўласьцівасьці прадастаўляюць узровень інкапсуляцыі вышэйшы, чым агульныя палі дадзеных.
Падтрымка ў мовах
[рэдагаваць | рэдагаваць крыніцу]Мовы праграмаваньня, якія падтрымліваюць уласьцівасцьі, — гэта Delphi/Free Pascal, Visual Basic, C#, D, eC, і Аб’ектны C 2.0. Пэўныя аб’ектна-арыентаваныя мовы, такія як C++ і Java, не падтрымліваюць уласьцівасьці і патрабуюць ад праграмоўцы замест гэтага вызначыць пару мэтадаў — мэтада для чытаньня (аксэсар) і мэтада для запісу.
У большасьці моваў уласьцівасьці рэалізаваныя парай мэтадаў для чытаньня і для запісу, але зьвяртацца да іх можна, выкарыстоўваючы той самы сынтаксыс, як і да агульных палёў. Калі пэўны мэтад з пары адсутнічае, то гэта ўласьцівасьць робіцца даступнай толькі для чытаньня альбо толькі для запісу, але апошняе сустракаецца дастаткова рэдка.
У пэўных мовах, дзе адсутнічае ўбудаваная падтрымка ўласьцівасьцяў, падобная канструкцыя можа быць рэалізаваная як адзін мэтад, які альбо вяртае значэньне, альбо зьмяняе яго ў залежнасьці ад кантэксту ягонага выкліку. Такія тэхнікі выкарыстоўваюцца, напрыклад у мове праграмаваньня Perl.
Прыклады выкарыстаньня
[рэдагаваць | рэдагаваць крыніцу]Delphi/Free Pascal
[рэдагаваць | рэдагаваць крыніцу]type TPen = class
private
m_Color: Integer;
function Get_Color: Integer;
procedure Set_Color(RHS: Integer);
public
property Color: Integer read Get_Color write Set_Color;
end;
function TPen.Get_Color: Integer;
begin
Result := m_Color
end;
procedure TPen.Set_Color(RHS: Integer);
begin
m_Color := RHS
end;
// атрыманьне доступу:
var pen: TPen;
// ...
pen.Color := not pen.Color;
(*
Delphi таксама падтрымлівае сынтаксіс «прамога поля»:
property Color: 'Integer read m_Color write Set_Color;
альбо
property Color: Integer read Get_Color write m_Color;
дзе кампілятар генэруе дакладна такі ж код для чытаньня і для запісу поля.
Гэта дазваляе выкарыстоўваць эфэктыўнасьць поля і бясьпеку ўласьцівасьці
(немагчыма атрымаць указальнік на уласьцівасьць, а таксама заўжды можна замяніць
прамы доступ да поля выклікам мэтаду).
*)
Visual Basic
[рэдагаваць | рэдагаваць крыніцу]' у клясе clsPen
Private m_Color As Long
Public Property Get Color() As Long
Color = m_Color
End Property
Public Property Let Color(ByVal RHS As Long)
m_Color = RHS
End Property
' атрыманьне доступу:
Dim pen As New clsPen
' ...
pen.Color = Not pen.Color
Visual Basic .Net
[рэдагаваць | рэдагаваць крыніцу]Public Class Pen
Private m_Color as Integer ' асабістае поле
Public Property Color as Integer ' агульнае поле
Get
Return m_Color
End Get
Set(ByVal Value as Integer)
m_Color = Value
End Set
End Property
End Class
' атрыманьне доступу:
Dim pen As New Pen()
' ...
pen.Color = Not pen.Color
C#
[рэдагаваць | рэдагаваць крыніцу]class Pen
{
private int m_Color; // асабістае поле
public int Color // агульнае поле
{
get
{
return m_Color;
}
set
{
m_Color = value;
}
}
}
// accessing:
Pen pen = new Pen();
// ...
pen.Color = ~pen.Color; // пабітавае дапаўненьне...
// яшчэ адзін дурнаваты прыклад:
pen.Color += 1; // a lot clearer than "pen.set_Color(pen.get_Color() + 1)"!
class Pen
{
private int m_color; // асабістае поле
// агульны мэтад чытаньня ўласьцівасьці
public int color () {
return m_color;
}
// агульны мэтад запісу ўласьцівасьці
public int color (int value) {
return m_color = value;
}
}
auto pen = new Pen;
pen.color = ~pen.color; // пабітавае дапаўненьне
// у гэтым выразе таксама можна выкарыстоўваць уласьівасьць для запісу: таксама як і звычайнае прысвойваньне
int theColor = (pen.color = 0xFF0000);
Python
[рэдагаваць | рэдагаваць крыніцу]Уласьцівасьці карэктна працуюць толькі для клясаў, створаных у новым стылі (клясы, якія маюць object
у якасьці продка), якія даступныя толькі ў Python 2.2 і больш новых вэрсіях (гл. адпаведную сэкцыю ў апісаньні Unifying types and classes in Python 2.2 (анг.)).
class Pen(object):
def __init__(self):
self.__color = 0 # "private" variable
self.__writeonly = "You can't read this!"
def _set_color(self, color):
self.__color = color
def _get_color(self):
return self.__color
color = property(_get_color, _set_color) # доступ на чытаньне/запіс трансьлюецца ў get/set-мэтады
def _set_writeonly(self, new_value):
self.__writeonly = new_value
writeonly = property(fset = _set_writeonly) # доступ толькі на запіс (спроба чытаньня генэруе выключэньне)
pen = Pen()
# атрыманьне доступу:
pen.color = ~pen.color # пабітавае дапаўненьне...
print pen.writeonly # узьнікае "AttributeError: unreadable attribute"
pen.writeonly = "Something Else" # <code>__writeonly</code> зараз зьяўляецца «Something Else»
print pen._Pen__writeonly
PHP
[рэдагаваць | рэдагаваць крыніцу]class Pen {
private $_color;
function __set($property, $value) {
switch ($property) {
case 'Color': $this->_color = $value; break;
}
}
function __get($property) {
switch ($property) {
case 'Color': return $this->_color; break;
}
}
}
$p = new Pen();
$p->Color = !$p->Color;
echo $p->Color;
class Pen { Color color; public property Color color { get { return color; } set { color = value; } } } // Прыклад выкарыстаньня Pen pen { red }; Pen pen { color = red }; pen.color = ~pen.color; pen.color += 10; pen.color.r = 255; pen.color = 0xFF0000; pen.color = { 255, 0, 0 }; pen.color = ColorHSV { 0, 100, 100 }; pen.color = ColorLab { 53, 79, 66 }; pen.color = ColorCMYK { 0, 100, 100, 0 };
Objective C 2.0
[рэдагаваць | рэдагаваць крыніцу]
@interface Pen : NSObject {
NSColor *color;
}
@property(copy) NSColor *color; // значэньні колеру заўжды капіююцца
@end
@implementation Pen
@synthesize color; // сынтэзаваньне мэтадаў доступу
@end
// Example Usage
Pen *pen = [Pen new];
pen.color = [NSColor blackColor];
float red = pen.color.redComponent;
[pen.color drawSwatchInRect:NSMakeRect(0, 0, 100, 100)];