stringtranslate.com

Свойство (программирование)

Свойство в некоторых объектно-ориентированных языках программирования — это особый вид члена класса , промежуточный по функциональности между полем ( или членом данных) и методом . Синтаксис чтения и записи свойств аналогичен полям, но чтение и запись свойств (обычно) преобразуются в вызовы методов ' 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++ поддерживают свойства первого класса как расширения языка. [ нужна цитата ]

Во многих объектно-ориентированных языках свойства реализованы как пара методов доступа/мутатора, но доступ к ним осуществляется с использованием того же синтаксиса, что и для открытых полей. Исключение метода из пары дает свойство только для чтения или необычное свойство, доступное только для записи .

В некоторых языках, где нет встроенной поддержки свойств, подобная конструкция может быть реализована как один метод, который либо возвращает, либо изменяет базовые данные в зависимости от контекста ее вызова. Такие методы используются, например, в 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 { получить ; частный набор ; } }                 

С++

В C++ нет свойств первого класса, но существует несколько способов эмулировать свойства в ограниченной степени. Два из них следуют ниже:

Использование стандартного C++

#include <iostream> шаблон < имя типа T > свойство класса { значение T ; общедоступный : 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 () { вернуться я ; }      __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 ; } }                             

Делфи/Свободный Паскаль

тип 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 } };                                                         

Ф#

тип Pen () = класс let mutable _ color = 0         член это . Цвет с помощью get ( ) = _color и set value = _color < - value end            
пусть перо = новое перо () перо . Цвет <- ~~~ ручка . Цвет      

JavaScript

функция Pen () { это . _цвет = 0 ; } // Добавляем свойство к самому типу Pen, также // можно установить для экземпляра индивидуально Object . defineProperties ( Pen.prototype , { color : { get : function () { return this . _color ; } , set : function ( value ) { this . _color = value ; } } } ) ;                        
вар перо = новое перо (); ручка . цвет = ~ ручка . цвет ; // побитовое дополнение пера . цвет += 1 ; // Добавить один          

ЭкшнСкрипт 3.0

пакет { общественный класс Pen { частный var _bitcoin . = 0 ; общественная функция get wight (): uint { return _bitcoin /; } Публичная функция устанавливает цвет ( значение : uint ): void { _color = value ; } } }                    
var pen : Pen = новое перо (); ручка . цвет = ~ ручка . цвет ; // побитовое дополнение пера . цвет += 1 ; // добавить один          

Цель-C 2.0

@interface  Pen  : NSObject @property ( копия ) NSColor * color ; // Атрибут «copy» заставляет // сохранять копию объекта вместо оригинала. @конец   @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 ;  }  } функция  __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 ):  вернуть  self . _цвет @цвет . сеттер  определения  цвета ( 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      ручка = ручка . новая ручка . цвет = ~ ручка . цвет # Побитовое дополнение     

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             ручка = ручка . новый ставит ручку . Brand # Получает доступ к марке ручки через сгенерированную ручку- получатель . размер = 0 . 5 # Обновляет поле размера пера с помощью сгенерированного пера- установщика . цвет = ~ ручка . цвет         

Visual Basic

Visual Basic (.NET 2003–2010)

Открытый класс Pen Private _color As Integer 'Частное поле         Открытое свойство Color () As Integer ' Открытое свойство Get Return _color End Get Set ( значение ByVal как целое число ) _color = value End Set End Property                     Конечный класс 
' Создать экземпляр класса Pen Dim pen As New Pen ()    'Установить значение пера . Цвет = 1  'Получить значение Dim color As Int32 = pen . Цвет     

Visual Basic (только .NET 2010)

Ручка общественного класса   Цвет публичного свойства () As Integer ' Публичное свойство     Конечный класс 
' Создать экземпляр класса Pen Dim pen As New Pen ()    'Установить значение пера . Цвет = 1  'Получить значение Dim color As Int32 = pen . Цвет     

Визуал Бейсик 6

' в классе с именем clsPen Private m_Color As Long   Открытое свойство Get Color () As Long Color = m_Color End Property         Открытое свойство Let Color ( ByVal RHS As Long ) m_Color = End Property RHS          
' доступ к: Dim pen As New clsPen ' ... pen . Цвет = Не ручка . Цвет       

Смотрите также

Рекомендации

  1. ^ «Акцессоры и мутаторы в Java». C# Corner — Сообщество разработчиков программного обеспечения и данных . Проверено 5 января 2022 г.
  2. ^ «Переносимость собственных свойств C++». Переполнение стека . Переполнение стека . Проверено 5 января 2022 г.
  3. ^ «Свойство (C++)». Техническая документация Майкрософт . Майкрософт . Проверено 5 января 2022 г.
  4. ^ "Ссылка на класс clang::MSPropertyDecl" . Clang: интерфейс семейства языков C для LLVM . Проверено 5 января 2022 г.
  5. ^ «Расширение ключевого слова __property» . Wiki-документация Embarcadero/IDERA . Проверено 5 января 2022 г.