Какие методы есть у свойства
Текущая версия страницы пока не проверялась опытными участниками и может значительно отличаться от версии, проверенной 28 февраля 2014;
проверки требуют 11 правок.
Свойство — способ доступа к внутреннему состоянию объекта, имитирующий переменную некоторого типа. Обращение к свойству объекта выглядит так же, как и обращение к структурному полю (в структурном программировании), но, в действительности, реализовано через вызов функции. При попытке задать значение данного свойства вызывается один метод, а при попытке получить значение данного свойства — другой.
При применении свойств
- можно задать значение по умолчанию, которое будет храниться в данном свойстве (или указать, что никакого значения по умолчанию не предполагается);
- можно указать, что это свойство только для чтения.
Как правило, свойство связано с некоторым внутренним полем объекта. Но свойству вообще может не быть сопоставлена ни одна переменная объекта, хотя пользователь данного объекта имеет дело с ним так, как если бы это было настоящее поле.
Свойства повышают гибкость и безопасность программирования, поскольку, являясь частью (открытого) интерфейса, позволяют менять внутреннюю реализацию объекта без изменения его полей. Свойства значительно облегчают модификацию программы в тех случаях, когда класс изначально был реализован с нарушением инкапсуляции, а в дальнейшем потребовалось изменить способ доступа к полю. При отсутствии в языке механизма свойств потребовалось бы искать и заменять обращения к полям на методы доступа.
Методы свойств[править | править код]
Во многих языках программирования свойства реализуются в виде пары методов: метод, получающий текущее значение свойства, называется акцессор (accessor); метод, задающий новое значение свойства, — мутатор (mutator).[источник не указан 1490 дней] В языках программирования, не поддерживающих свойства, например, C++ и Java, пара из акцессора и мутатора является общепринятым суррогатом для их замены.
Принято называть методы свойств именем свойства с приставками get и set: например, для свойства Xyzzy — get_Xyzzy и set_Xyzzy (традиционный стиль Си) либо GetXyzzy и SetXyzzy (стиль CamelCase). В связи с этой схемой наименования за методами свойств закрепились жаргонные названия getter и setter.
Примеры[править | править код]
Свойства в C#[править | править код]
Свойства в C# — поля с логическим блоком, в котором есть ключевые слова get и set.
Пример класса со свойством:
{
private int p_field;
public int Field
{
get
{
return p_field;
}
private set
{
p_field = value;
}
}
}
Свойства в VB.NET[править | править код]
Пример реализации в VB.NET. Если нужно реализовать свойство только для чтения или только для записи, применяются модификаторы ReadOnly и WriteOnly. Свойство может быть параметризованным. Также может быть свойством по умолчанию, для этого необходимо добавить модификатор Default
Dim F As New Foo
F.Data = 5
F.Item(0) = 5
F(0) = 5 ‘Запись в свойство
Console.WriteLine(F(0)) ‘Чтение свойства
End Sub
Public Class Foo
Private m_Data As Integer
Private m_Arr() As Integer = {1, 2, 3, 4, 5}
Public Property Data As Integer
Set(Value As Integer) ‘Сеттер
m_Data = Value
End Set
Get
Return m_Data ‘Геттер
End Get
End Property
Public Default Property Item(Param As Integer) As Integer ‘Параметризованное свойство по умолчанию
Set(Value As Integer)
m_Arr(Param) = Value
End Set
Get
Return m_Arr(Param)
End Get
End Property
End Class
Свойства в Delphi[править | править код]
Для описания свойства в Delphi служит слово property.
Пример класса со свойством:
private
FMyField: Integer;
procedure SetMyField(const Value: Integer);
function GetMyField: Integer;
public
property MyField: Integer read GetMyField write SetMyField;
end;
function TMyClass.GetMyField: Integer;
begin
Result := FMyField;
end;
procedure TMyClass.SetMyField(const Value: Integer);
begin
FMyField := Value;
end;
Свойства в ActionScript[править | править код]
{
private _foo : int;
public function get foo () : int {
return _foo;
}
public function set foo (foo : int) : void {
_foo = foo;
}
}
Свойства в Objective C[править | править код]
{
NSString *var_name;
}
@property(retain) NSString *var_name;
@end
@implementation Company
@synthesize var_name;
@end
Свойства в Ruby[править | править код]
Описания свойства в Ruby ничем не отличается от описания метода. Например, для создания свойства duration у класса Song нужно описать методы duration и duration=(value)
def duration
@duration
end
def duration=(value)
@duration = value
end
end
Однако простое обращение к внутренней переменной объекта может быть заменено на вызов метода attr_accessor :duration
attr_accessor :duration
end
Более интересным будет пример создания свойства duration_in_minutes, которое будет возвращать или устанавливать время длительности в минутах:
def duration_in_minutes
@duration/60.0
end
def duration_in_minutes=(value)
@duration = (value*60).to_i
end
end
При этом изменение свойства duration_in_minutes повлияет на свойство duration. Например
song.duration_in_minutes = 1.2
print song.duration # напечатает 72
Свойства в Python[править | править код]
Набор методов с декораторами определяет способы работы со свойством (чтение, запись, удаление). Если какой-то из методов убрать (за исключением @property), теряется возможность работать со свойством соответствующим образом.
Пример класса со свойством:
def __init__(self):
self.__x = None
@property
def x(self):
return self.__x
@x.setter
def x(self, value):
self.__x = value
@x.deleter
def x(self):
self.__x = None
>>> a.x
>>> a.x = 2
>>> a.x
2
>>> del a.x
>>> a.x
>>>
См. также[править | править код]
- Событие
- Метод
Свойства
Последнее обновление: 03.10.2019
Кроме обычных методов в языке C# предусмотрены специальные методы доступа, которые называют свойства.
Они обеспечивают простой доступ к полям классов и структур, узнать их значение или выполнить их установку.
Стандартное описание свойства имеет следующий синтаксис:
[модификатор_доступа] возвращаемый_тип произвольное_название
{
// код свойства
}
Например:
class Person
{
private string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
}
Здесь у нас есть закрытое поле name и есть общедоступное свойство Name. Хотя они имеют практически одинаковое название за исключением регистра,
но это не более чем стиль, названия у них могут быть произвольные и не обязательно должны совпадать.
Через это свойство мы можем управлять доступом к переменной name. Стандартное определение свойства содержит блоки get
и set. В блоке get мы возвращаем значение поля, а в блоке set устанавливаем. Параметр value представляет передаваемое значение.
Мы можем использовать данное свойство следующим образом:
Person p = new Person();
// Устанавливаем свойство — срабатывает блок Set
// значение «Tom» и есть передаваемое в свойство value
p.Name = «Tom»;
// Получаем значение свойства и присваиваем его переменной — срабатывает блок Get
string personName = p.Name;
Возможно, может возникнуть вопрос, зачем нужны свойства, если мы можем в данной ситуации обходиться обычными полями класса? Но свойства
позволяют вложить дополнительную логику, которая может быть необходима, например, при присвоении переменной класса какого-либо значения.
Например, нам надо установить проверку по возрасту:
class Person
{
private int age;
public int Age
{
set
{
if (value < 18)
{
Console.WriteLine(«Возраст должен быть больше 17»);
}
else
{
age = value;
}
}
get { return age; }
}
}
Если бы переменная age была бы публичной, то мы могли бы передать ей извне любое значение, в том числе отрицательное. Свойство же позволяет скрыть данные в объеты и
опосредовать к ним доступ.
Блоки set и get не обязательно одновременно должны присутствовать в свойстве. Если свойство определяют только блок get, то такое свойство доступно только для
чтеня — мы можем получить его значение, но не установить. И, наоборот, если свойство имеет только блок set, тогда это свойство доступно только для записи — можно
только установить значение, но нельзя получить:
class Person
{
private string name;
// свойство только для чтения
public string Name
{
get
{
return name;
}
}
private int age;
// свойство только для записи
public int Age
{
set
{
age = value;
}
}
}
Хотя в примерах выше свойства определялись в классе, но точно также мы можем определять и использовать свойства в структурах.
Модификаторы доступа
Мы можем применять модификаторы доступа не только ко всему свойству, но и к отдельным блокам — либо get, либо set:
class Person
{
private string name;
public string Name
{
get
{
return name;
}
private set
{
name = value;
}
}
public Person(string name)
{
Name = name;
}
}
Теперь закрытый блок set мы сможем использовать только в данном классе — в его методах, свойствах, конструкторе, но никак не в другом классе:
Person p = new Person(«Tom»);
// Ошибка — set объявлен с модификатором private
//p.Name = «John»;
Console.WriteLine(p.Name);
При использовании модификаторов в свойствах следует учитывать ряд ограничений:
Модификатор для блока set или get можно установить, если свойство имеет оба блока (и set, и get)
Только один блок set или get может иметь модификатор доступа, но не оба сразу
Модификатор доступа блока set или get должен быть более ограничивающим, чем модификатор доступа свойства. Например,
если свойство имеет модификатор public, то блок set/get может иметь только модификаторы protected internal, internal, protected, private
Автоматические свойства
Свойства управляют доступом к полям класса. Однако что, если у нас с десяток и более полей, то определять каждое поле и писать для него однотипное свойство
было бы утомительно. Поэтому в фреймворк .NET были добавлены автоматические свойства. Они имеют сокращенное объявление:
class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Person(string name, int age)
{
Name = name;
Age = age;
}
}
На самом деле тут также создаются поля для свойств, только их создает не программист в коде, а компилятор автоматически генерирует при компиляции.
В чем преимущество автосвойств, если по сути они просто обращаются к автоматически создаваемой переменной, почему бы напрямую не обратиться к переменной без автосвойств?
Дело в том, что в любой момент времени при необходимости мы можем развернуть автосвойство в обычное свойство, добавить в него какую-то определенную логику.
Стоит учитывать, что нельзя создать автоматическое свойство только для записи, как в случае со стандартными свойствами.
Автосвойствам можно присвоить значения по умолчанию (инициализация автосвойств):
class Person
{
public string Name { get; set; } = «Tom»;
public int Age { get; set; } = 23;
}
class Program
{
static void Main(string[] args)
{
Person person = new Person();
Console.WriteLine(person.Name); // Tom
Console.WriteLine(person.Age); // 23
Console.Read();
}
}
И если мы не укажем для объекта Person значения свойств Name и Age, то будут действовать значения по умолчанию.
Стоит отметить, что в структурах мы не можем использовать инициализацию автосвойств.
Автосвойства также могут иметь модификаторы доступа:
class Person
{
public string Name { private set; get;}
public Person(string n)
{
Name = n;
}
}
Мы можем убрать блок set и сделать автосвойство доступным только для чтения. В этом случае для хранения значения этого свойства для него неявно будет создаваться поле с модификатором readonly, поэтому следует учитывать, что подобные get-свойства
можно установить либо из конструктора класса, как в примере выше, либо при инициализации свойства:
class Person
{
public string Name { get;} = «Tom»
}
Сокращенная запись свойств
Как и методы, мы можем сокращать свойства. Например:
class Person
{
private string name;
// эквивалентно public string Name { get { return name; } }
public string Name => name;
}
chronomaster
22 февраля 2018 в 12:41
- Как вы называете парные методы Get/Set? Допускается ли делать их несимметричными? А если для свойства используется глагол Is? А если какой-нибудь модальный глагол вроде Can?
- Допускается ли вместо Get/Set использовать пары Is/Set?
- И если есть ограничения, то это ваш сознательный выбор или корпоративный стандарт?
У нас в компании по этому поводу написано следующее (выдержка из инструкции программиста, часть «Рекомендация по образованию имен»):
Методы получения бинарного атрибута
Имя метода получения бинарного атрибута должно быть предикатом (вопросом, на который можно ответить Да или Нет). В большинстве случаев имя метода должно начинаться с глаголов Is или Has.
Методы получения и установки небинарного атрибута
Допускается добавление к названию метода получения атрибута глагола Get. Если кроме метода получения атрибута в классе есть также метод установки атрибута, то названия этих методов должны начинаться с глаголов Get и Set соответственно.
Теперь же возьмём открытое у меня «произвольное» решение, состоящее примерно из 50 проектов, большей частью касающихся оболочки продукта, и включающее в себя около 5000 заголовочный файлов. И посмотрим, какие именования там встречаются:
На круговой диаграмме показано относительное распределение различных “get”-методов. На остальных по смысловым глаголам: Is, Can, Has, Need, Should. Только будьте внимательны, некоторые диаграммы строил грамотный PM.
Анализ найденного показал, что есть небольшое число парных Is/Set методов, у которых метод Set не принимает никаких параметров. Т.е. значение по умолчанию false, а set-метод его взводит, и отменить данный переход никак нельзя. Это осмысленно для IsFailed() / SetFailed(). Но во многих случаях данное ограничение вытекает скорее из ограничений UI (что сейчас пользователь так не может сделать), чем из логики свойства.
Также надо заметить, что поиск по чужому решению показал кардинально отличающееся распределение. Поэтому использование конкретных модальных глаголов, скорее всего, связано с людьми в команде, чем c правилами организации.
Так как же правильно назвать метод? NeedDoSomething или ShouldDoSomething? Какой модальный глагол выбрать? Попробуем ответить на этот вопрос. Совершенно очевидно, что таких методов должно быть шесть, а как их использовать указано ниже:
bool Do( TАction type, IObject* obj ) {
// надо ли вообще париться
if( !detector.ShouldDo( type, obj ) ) {
return false;
}
// разрешено ли действие
if( !callback.MayDo( type, obj ) && !DareToDo( type ) ) {
// нам запретили выполнить действие и у нас нет смелости нарушить указание
// проверим на обязательность действия – и кинем исключение, если надо
check( !detector.MustDo( type, obj ), ERR_MUST_NOT_MAY );
return false;
}
// выполним действие
foreach( executor in executors ) {
if( executor.OughtToDo( type, obj ) ) {
if( executor.CanDo( obj ) ) {
executor.Do( obj );
}
check( !detector.MustDo( type, obj ), ERR_MUST_NOT_CAN );
return false;
}
};
// executor должен быть
check( false, ERR_EXEC_NOT_FOUND );
}
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
9,3%У нас запрещено использовать методы без Get/Set-префиксов19
53,4%Можно использовать связки Is вместо Get109
36,3%Можно использовать Has вместо Get74
34,8%Можно использовать Can вместо Get71
22,1%Можно использовать Should/Need/…45
55,4%Как хочу, так и пишу. Правила для маменькиных сынков113
Теги:
- программирование как искусство
- именование переменных
Хабы:
Блог компании ABBYY
Программирование
24.02.2010, 22:55 | |||
| |||
Как различить методы и свойства? Друзья! Как вы их различаете? Синтаксис ведь один! Вот например: Очень странно. (Был класс, были переменные типа <имя класса> и к этим переменным применялись функции, в классе определённые- суть методы. НУ и потом детали всякие. Может, и громоздче, но однозначно, то есть функция суть таковая и ничего более, а тут location и объект и свойство… бр…) ПОмогите пожалуйста разобраться. Спасибо. |
24.02.2010, 23:05 | |||
| |||
А что странного в том, что свойство может быть ссылкой на объект? Кроме свойств и методов есть еще сеттеры и геттеры |
24.02.2010, 23:12 | |||
| |||
Мне знаете, ли не до шуток. Я и так Вам верю, что Вы много знаете, могли бы не писать ерудны, не тратит своё и моё время, если по какой-то причине не хотите помочь. Извините. |
24.02.2010, 23:18 | ||||
| ||||
В JavaScript у объекта только свойства и могут быть (если не считать сеттеров и геттеров), а метод — это просто ссылка на объект, который является функцией Ну проверить тип, можно, например, так: var obj = { alert([ «obj.property1 is » + typeof obj.property1, ].join(«n»));
а где я ерунду написал?
за мое время переживать не стоит
|
24.02.2010, 23:37 | |||
| |||
А различаете вы их как? С типами понятно, спасибо. Но вот тот же join, допустим. Я ткнул в справочник, посмотрел, для чего он нужен. Но вот что он такое- метод или свойство так и не понял, а в справочнике не написано. Ну раз он имеет аргументы, наверное метод. Неохота гадать, показывать невежество. Должно быть какое-то различие в синтаксисе, да ведь? Скобки () присутствуют не всегда. |
24.02.2010, 23:49 | |||
| |||
Зачем какие-то различия в синтаксисе, если у объекта могут быть только свойства? Методом, называют свойство объекта, являющееся ссылкой на функцию, потому что так привычнее, такая терминология используется в других языках, но от этого какой-то другой конструкцией в JavaScript оно не становится. var obj = {}; obj.abc = function () {}; // здесь obj.abc — метод obj.abc = 1; // а тут уже obj.abc — свойство Какое может быть различие в доступе к свойствам при условии, что это свойство может быть динамически изменено?
|
25.02.2010, 00:09 | |||
| |||
Попробую разобраться, спасибо. |
25.02.2010, 00:12 | |||
| |||
Еще есть сеттеры и геттеры, но механизм их создания доступен JS-программисту не во всех браузерах: var obj = { obj.__defineSetter__(«propertyX», function (a) { obj.__defineGetter__(«propertyX», function () { obj.propertyX = 2; alert(obj.x); Так же, возможно, реализованы и window.location, и document.body.innerHTML. Хотя, сами эти сеттеры и геттеры, наверное, тоже свойства, но с определенной пометкой и обработчиками, тут я не знаю, как оно внутри работает, могу только догадываться.
|
25.02.2010, 00:39 | |||
| |||
А что такое свойство? А вот это что? Ну то есть я увидел создание объекта obj (Какого типа? Или это напрасный вопрос- следствие языка С?) Но вот дальше вообще не понимаю ничё. Как может единица быть свойством? Чё-то вообще не пойму. Ну а потом отсюда вот взял var anchorCount=document.anchors.length |
25.02.2010, 00:55 | ||||||
| ||||||
типа Object
obj — объект Значением свойства может быть не только примитив (число, строка и т.д.), но и ссылка (Reference) на другой объект, функцию, массив.
У объекта document есть свойство anchors, значением которого является ссылкой на массив. У этого массива есть свойство length. Читайте статьи на этом сайте или для глубокого понимания Тонкости ECMAScript. Дальше теорию рассказывать не охото.
|