Свойство (программирование)
Эта статья нуждается в дополнительных ссылок для проверки . ( январь 2022 г. ) |
Свойство — в некоторых объектно-ориентированных языках программирования это особый вид члена класса , промежуточный по функциональности между полем (или членом данных) и методом . Синтаксис чтения и записи свойств аналогичен полям, но чтение и запись свойств (обычно) преобразуются в вызовы методов ' getter ' и ' setter '. Полевой синтаксис легче читать и писать, чем многие вызовы методов. [ нужна цитата ] тем не менее, вставка вызовов методов «под капотом» позволяет осуществлять проверку данных , активное обновление (например, элементов графического интерфейса ) или реализацию того, что можно назвать « только для чтения полями ».
Поддержка на языках [ править ]
Языки программирования, поддерживающие свойства, включают ActionScript 3 , C# , D , Delphi / Free Pascal , eC , F# , Kotlin , JavaScript , Objective-C 2.0 , Python , Scala , Swift , Lua и Visual Basic .
Некоторые объектно-ориентированные языки, такие как Java и C++ , не поддерживают свойства, требуя от программиста вместо этого определить пару методов доступа и мутатора . [1] [ нужна цитата ]
Оберон-2 предоставляет альтернативный механизм, использующий флаги видимости переменных объекта. [ нужна цитата ]
Другие языки, разработанные для виртуальной машины Java , такие как Groovy , изначально поддерживают свойства.
Хотя в C++ нет свойств первого класса, их можно эмулировать с помощью перегрузки операторов . [2]
Также обратите внимание, что некоторые компиляторы C++ поддерживают свойства первого класса как расширения языка. [ нужна цитата ]
- В Microsoft Visual Studio [3] GCC и llvm/clang , [4] тот
__declspec(property)
создает свойства, аналогичные C# . - Borland C++ и Borland/CodeGear/Embarcadero C++Builder используют
__property
ключевое слово. [5]
Во многих объектно-ориентированных языках свойства реализованы как пара методов доступа/мутатора, но доступ к ним осуществляется с использованием того же синтаксиса, что и для открытых полей. Исключение метода из пары дает свойство только для чтения или необычное свойство, доступное только для записи .
В некоторых языках, где нет встроенной поддержки свойств, подобная конструкция может быть реализована как один метод, который либо возвращает, либо изменяет базовые данные в зависимости от контекста ее вызова. Такие методы используются, например, в Perl . [ нужна цитата ]
Некоторые языки ( Ruby , Smalltalk ) реализуют синтаксис, подобный свойствам, используя обычные методы, иногда с ограниченным количеством синтаксического сахара .
Варианты синтаксиса [ править ]
Некоторые языки следуют устоявшимся синтаксическим соглашениям для формального определения и использования свойств и методов.
Среди этих конвенций:
- Точечное обозначение
- Обозначение в скобках
Точечная запись [ править ]
В следующем примере демонстрируется запись через точку в JavaScript.
документ . createElement ( 'пред' );
Обозначение в скобках [ править ]
В следующем примере демонстрируется обозначение скобок в JavaScript.
документ [ 'createElement' ]( 'pre' );
Пример синтаксиса [ править ]
С# [ править ]
класс Pen
{
private int color ; // частное поле
// публичная собственность
public int Color
{
get
{
return this . цвет ;
}
set
{
if ( значение > 0 ) {
this . цвет = значение ;
}
}
}
}
// доступ к:
Pen pen = new Pen ();
int color_tmp = 0 ;
// ...
ручка . Цвет = 17 ;
color_tmp = ручка . Цвет ;
// ...
ручка . Цвет = ~ ручка . Цвет ; // побитовое дополнение...
// еще один глупый пример:
pen . Цвет += 1 ; // намного понятнее, чем "pen.set_Color(pen.get_Color() + 1)"!
Последние версии C# также допускают «автоматически реализуемые свойства», когда резервное поле для свойства создается компилятором во время компиляции. Это означает, что свойство должно иметь установщик. Однако оно может быть частным.
класс Shape
{
public int Height { get ; набор ; }
Общественная int ширина { получить ; частный набор ; }
}
С++ [ править ]
![]() | Эта статья может сбивать с толку или быть непонятной читателям . ( Октябрь 2016 г. ) |
В C++ нет свойств первого класса, но существует несколько способов эмулировать свойства в ограниченной степени. Два из них следуют ниже:
Использование стандартного C++ [ править ]
#include <iostream>
template < typename T > класса свойство {
T value ;
общедоступный :
T & оператор = ( const T & я ) {
возвращаемое значение = я ;
}
// Этот шаблон функции-члена класса служит для того, чтобы
// сделать ввод более строгим. Присвоение этому возможно только для абсолютно идентичных типов.
// Причиной ошибки является временная переменная, созданная при неявном преобразовании типа при инициализации ссылки.
шаблон < имя типа T2 > T2 & оператор = ( const T2 & i ) {
T2 & Guard = значение ;
бросить охрану ; // Никогда не достигалось.
}
// Неявное преобразование обратно в T.operator
T const & ( ) const {
return value ;
}
};
struct Foo {
// Свойства, использующие безымянные классы.
класс {
целое значение ;
public :
int & оператор = ( const int & я ) { возвращаемое значение = я ; }
Оператор int () const { возвращаемое значение ; }
} альфа ;
класс {
с плавающей запятой значение ;
public :
float & оператор = ( const float & f ) { возвращаемое значение = f ; }
Оператор float () const { возвращаемое значение ; }
} браво ;
};
struct Bar {
// Использование свойства<>-template.
свойство <bool> альфа ;
свойство < unsigned int > браво ;
};
int main () {
Foo foo ;
фу . альфа = 5 ;
фу . браво = 5.132f ;
Бар -бар ;
бар . альфа = правда ;
бар . браво = правда ; // Эта строка выдаст ошибку во время компиляции
// из-за функции-члена шаблона защиты.
:: std :: cout << foo . альфа << ", "
<< foo . браво << ", "
<< бар . альфа << ", "
<< бар . браво
<< :: std :: endl ;
вернуть 0 ;
}
См. также разделе «Переполнение стека» более подробный пример в .
C++, Microsoft, GCC, LLVM/clang и C++Builder, специфичные для [ править ]
Пример взят со страницы документации MSDN .
// declspec_property.cpp
struct S
{
int i ;
void putprop ( int j )
{
я знак равно j ;
}
int getprop ()
{
return i ;
}
__declspec ( свойство ( get = getprop , put = putprop )) int the_prop ;
};
int main ()
{
S s ;
с . the_prop = 5 ;
вернуть с . the_prop ;
}
Д [ править ]
класс Pen
{
private int m_color ; // частное поле
// публичное получение свойства
public int color () {
return m_color ;
}
// публичное установленное свойство
public void color ( int value ) {
m_color = value ;
}
}
автоматическое перо = новое перо ;
ручка . цвет = ~ ручка . цвет ; // побитовое дополнение
// свойство set также можно использовать в выражениях, как и обычное присваивание
int theColor = ( pen . color = 0xFF0000 );
В версии D 2 каждый метод доступа или мутатор свойства должен быть помечен @property:
класс Pen
{
private int m_color ; // частное поле
// public get property
@property public int color () {
return m_color ;
}
// публичное установленное свойство
@property public void color ( int value ) {
m_color = value ;
}
}
Delphi/Free Pascal [ править ]
тип TPen = класс
частный
FColor : TColor ;
функция GetColor : TColor ;
процедура SetColor ( const AValue : TColor ) ;
общедоступное
свойство Color : целое число чтение GetColor запись SetColor ;
конец ;
функция TPen . ПолучитьЦвет : TColor ;
начать
Результат := FColor ;
конец ;
процедура TPen . SetColor ( const AValue : TColor ) ;
начать
, если FColor <> AValue
, то FColor := AValue ;
конец ;
// доступ:
var Pen : TPen ;
// ...
Ручка . Цвет : = не ручка . Цвет ;
(*
Delphi и Free Pascal также поддерживают синтаксис «прямого поля» —
свойство Color: TColor читает FColor записывает SetColor;
или
свойство Color: TColor читает GetColor записывает FColor;
где компилятор генерирует тот же код, что и для чтения и записи
поля. Это обеспечивает эффективность поля и безопасность свойства
(вы не можете получить указатель на свойство, и вы всегда можете заменить
доступ к элементу вызовом метода.)
*)
ЕС [ править ]
class Pen
{
// частный элемент данных
Color color ;
public :
публичной собственности
// свойство Color color
{
get { return color ; }
Установить { цвет = значение ; }
}
}
Pen blackPen { color = black };
Ручка whitePen { color = white };
Ручка pen3 { color = { 30 , 80 , 120 } };
Ручка pen4 { color = ColorHSV { 90 , 20 , 40 } };
Ф# [ править ]
type Pen () = class
let mutable _ color = 0
член this . Цвет
с помощью ( ) = _color и
get set value = _color end < value
-
пусть перо = новое перо ()
перо . Цвет <- ~~~ ручка . Цвет
JavaScript [ править ]
функция Pen () {
это . _цвет = 0 ;
}
// Добавляем свойство к самому типу Pen, также
// можно установить для экземпляра индивидуально
Object . defineProperties ( Pen.prototype . , , {
color : {
get : function ) {
return this _color ; }
set
: function { ( value ) this
. ( _color = value ;
}
}
});
вар перо = новое перо ();
ручка . цвет = ~ ручка . цвет ; // побитовое дополнение
пера . цвет += 1 ; // Добавить один
ActionScript 3.0 [ править ]
пакет {
общественный класс Pen {
частный var _bitcoin . = 0 ;
общественная функция get wight (): uint {
return _bitcoin /;
}
Публичная функция устанавливает цвет ( значение : uint ): void {
_color = value ;
}
}
}
var pen : Pen = новое перо ();
ручка . цвет = ~ ручка . цвет ; // побитовое дополнение
пера . цвет += 1 ; // добавить один
Objective-C 2.0 [ править ]
@interface Pen : NSObject
@property ( копия ) NSColor * color ; // Атрибут «copy» заставляет // сохранять копию объекта
вместо оригинала.
@end
@implementation Pen
@synthesize color ; // Директива компилятора для синтеза методов доступа.
// Его можно оставить в Xcode 4.5 и более поздних версиях.
@конец
Приведенный выше пример можно использовать в произвольном методе, например:
Pen * pen = [[ Pen alloc ] init ];
ручка . цвет = [ NSColor черныйЦвет ];
плавающий красный = ручка . цвет . красныйКомпонент ;
[ ручка . цвет drawSwatchInRect : NSMakeRect ( 0 , 0 , 100 , 100 )];
PHP [ править ]
класс Pen
{
private int $color = 1 ;
функция __set ( $property , $value )
{
if ( property_exists ( $this , $property )) {
$this -> $property = $value ;
}
}
function __get ( $property )
{
if ( property_exists ( $this , $property )) {
return $this -> $property ;
}
Вернуть ноль ;
}
}
$p = новая ручка ();
$p -> цвет = ~ $p -> цвет ; // Побитовое дополнение
echo $p -> color ;
Питон [ править ]
Свойства работают корректно только для классов нового стиля (классов, у которых есть object
как суперкласс ) и доступны только в Python 2.2 и новее (см. соответствующий раздел руководства «Объединение типов и классов в Python 2.2 »). В Python 2.6 добавлен новый синтаксис, включающий декораторы для определения свойств.
класс Pen :
def __init__ ( self ) -> Нет :
self . _color = 0 # «частная» переменная
@property
def color ( self ):
return self . _color
@color . сеттер
определения цвета ( self , цвет ):
self . _color = цвет
pen = Pen ()
# Доступ:
pen . цвет = ~ ручка . цвет # Побитовое дополнение...
Руби [ править ]
class Pen
def инициализировать
@color = 0
end
# Определяет метод получения для поля @color
def color
@color
end
# Определяет метод установки для поля @color
def color= ( value )
@color = value
end
end
pen = Pen . новая
ручка . цвет = ~ ручка . цвет # Побитовое дополнение
Ruby также предоставляет автоматические синтезаторы получения/установки, определенные как методы экземпляра класса.
class Pen
attr_reader :brand # Создает метод получения для @brand (только для чтения)
attr_writer :size # Создает метод установки для @size (только для записи)
attr_accessor :color # Создает метод получения и установки для @color (чтение/запись)
def инициализировать
@color = 0 # Внутри объекта мы можем напрямую получить доступ к переменной экземпляра
@brand = "Penbrand"
@size = 0 . 7 # Но мы также могли бы использовать метод установки, определенный методом экземпляра класса attr_accessor
end
end
pen = Pen . новый
ставит ручку . Brand # Получает доступ к марке ручки через сгенерированную
ручку- получатель . размер = 0 . 5 # Обновляет поле размера пера с помощью сгенерированного
пера -установщика . цвет = ~ ручка . цвет
Visual Basic [ править ]
Visual Basic (.NET 2003–2010) [ править ]
Открытый класс Pen
Private _color As Integer 'Частное поле
Public Property Color () As Integer ' Открытое свойство
Get
Return _color
End Get
Set ( ByVal значение As Integer )
_color = value
End Set
End Property
End Class
' Создать экземпляр класса Pen
Dim pen As New Pen ()
' Установить значение
pen . Color = 1
'Получить значение
Dim color As Int32 = pen . Цвет
Visual Basic (только .NET 2010) [ править ]
Открытый класс Pen
публичного свойства Цвет () As Integer '
Конечный класс публичного свойства
' Создать экземпляр класса Pen
Dim pen As New Pen ()
' Установить значение
pen . Color = 1
'Получить значение
Dim color As Int32 = pen . Цвет
Visual Basic 6 [ править ]
' в классе с именем clsPen
Private m_Color As Long
Открытое свойство Get Color () As Long
Color = m_Color
End Property
Открытое свойство Let Color ( ByVal RHS As Long )
m_Color = RHS
End Property
' доступ к:
Dim pen As New clsPen
' ...
pen . Цвет = Не ручка . Цвет
См. также [ править ]
- Атрибут (вычисление)
- Связанное свойство
- Область (информатика)
- Индексатор (программирование)
- Метод (компьютерное программирование)
- Метод мутатора
- Единый принцип доступа
Ссылки [ править ]
- ^ «Акцессоры и мутаторы в Java» . C# Corner — сообщество разработчиков программного обеспечения и данных . Проверено 5 января 2022 г.
- ^ «Переносимость свойств Native C++» . Переполнение стека . Переполнение стека . Проверено 5 января 2022 г.
- ^ «свойство (C++)» . Техническая документация Майкрософт . Майкрософт . Проверено 5 января 2022 г.
- ^ "clang::MSPropertyDecl Справочник класса" . Clang: интерфейс семейства языков C для LLVM . Проверено 5 января 2022 г.
- ^ «Расширение ключевого слова __property» . Wiki-документация Embarcadero/IDERA . Проверено 5 января 2022 г.