Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Методы получения и установки значений свойств

Поиск

 

type

TDelimitedReader = class

...

FActive: Boolean;

...

procedure SetActive(const AActive: Boolean);

property Active: Boolean read FActive write SetActive; // Свойство

end;

 

Ключевые слова read и write называются спецификаторами доступа. После read указывается поле или метод, к которому происходит обращение при чтении значения свойства, а после write –поле или метод, к которому происходит обращение при записи значения свойства. Чтобы имена свойств не совпадали с именами полей, последние принято писать с буквы F(от англ. Field).

 

Обращение к свойствам выглядит в программе как обращение к полям:

var

Reader: TDelimitedReader;

IsOpen: Boolean;

...

Reader.Active:= True; // ЭквивалентноReader.SetActive(True);

IsOpen:= Reader.Active; // ЭквивалентноIsOpen:= Reader.FActive

 

Если один из спецификаторов доступа опущен, то значение свойства можно либо только читать, либо только записывать.

 

Технология ООП в среде Delphi предписывает избегать прямого обращения к полям, создавая вместо этого соответствующие свойства. Это упорядочивает работу с объектами, изолируя их данные от непосредственной модификации.

Методы чтения и записи значений свойств подчиняются определенным правилам. Метод чтения свойства – это всегда функция, возвращающая значение того же типа, что и тип свойства. Метод записи свойства – это обязательно процедура, принимающая параметр того же типа, что и тип свойства. В остальных отношениях это обычные методы объекта.

 

Использование методов для получения и установки свойств позволяет проверить корректность значения свойства, сделать дополнительные вычисления, установить значения зависимых полей и т.д.

 

Свойства-массивы

Кроме обычных свойств в объектах существуют свойства-массивы (array properties).

Свойство–массив – это индексированное множество значений.

 

type

TDelimitedReader = class

...

FItems: array of string;

...

function GetItem(Index: Integer): string;

...

property Items[Index: Integer]: string read GetItem;

end;

function TDelimitedReader.GetItem(Index: Integer): string;

begin

Result:= FItems[Index];

end;

 

В описании свойства-массива разрешено использовать только методы, но не поля. В этом состоит отличие свойства-массива от обычного свойства.

 

Основная выгода от применения свойства-массива – возможность выполнения итераций с помощью цикла for, например:

for i:= 0 toReader.ItemCount - 1 do

Writeln(Reader.Items[i]);

 

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

Свойства-массивы имеют два важных отличия от обычных массивов:

1) их индексы не ограничиваются диапазоном;

2) индексы могут иметь любой тип данных, а не только Integer:

 

Reader.Items['FirstName']:= 'Alexander';

 

Операции целиком со всем свойством-массивом запрещены; разрешены операции только с его элементами.

 

Свойство-массив можно сделать основным свойством объектов данного класса. Для этого в описание свойства добавляется слово default:

 

type

TDelimitedReader = class

...

Property Items[Index: Integer]: string readGetItem; default;

...

end;

 

Такое объявление свойства Items позволяет рассматривать сам объект класса TDelimitedReader как массив и опускать имя свойства-массива при обращении к нему из программы, например:

 

For i:= 0 to Reader. ItemCount - 1 do

Writeln(Reader [i]);

 

Следует помнить, что только свойства-массивы могут быть основными свойствами объектов; для обычных свойств это недопустимо.

 

Один и тот же метод может использоваться для получения (установки) значений нескольких свойств одного типа. В этом случае каждому свойству назначается целочисленный индекс, который передается в метод чтения (записи) первым параметром.

 

type

TDelimitedReader = class

...

property FirstName: string index 0 read GetItem;

property LastName: string index 1 read GetItem;

property Phone: string index 2 read GetItem;

end;

 

Обращения к свойствам FirstName, LastName и Phone заменяются компилятором на вызовы одного и того же метода GetItem, но с разными значениями параметра Index:

var

Reader: TDelimitedReader;

...

Writeln(Reader.FirstName); // Эквивалентно: Writeln(Reader.GetItem(0));

Writeln(Reader.LastName); // Эквивалентно: Writeln(Reader.GetItem(1));

Writeln(Reader.Phone); // Эквивалентно: Writeln(Reader.GetItem(2));


 

Индексаторы

C#

Индексаторы очень похожи на свойства. Формально синтаксис определения индексатора таков:


[атрибуты] [модификаторы] тип this [список-формальных-параметров] { set get }

Или, если это индексатор в интерфейсе, таков:

[атрибуты] [модификаторы] тип интерфейс.this [список формальных параметров] { set get }


АТРИБУТЫ — дополнительная информация об индексаторе. Наиболее значимым для индексаторов является атрибут Name. Задание Name позволяет дать имя индексатору для того, чтобы его могли использовать другие языки, не поддерживающие индексаторы. По умолчанию все индексаторы вашего класса имеют Name, равный Item;


МОДИФИКАТОРЫ — модификаторы доступа и директивы. К индексатору применимы почти все стандартные директивы С#. Он может быть скрыт, перегружен, сделан виртуальным, но есть одно исключение, индексатор не может быть static;


СПИСОК ФОРМАЛЬНЫХ ПАРАМЕТРОВ — указывает параметры, посредством которых осуществляется индексация. Передается в get и set, которые используются в индексаторе так же, как в свойствах, get применяется для вычисления индексатора по заданному списку формальных параметров, a set – для изменения индексатора, set получает в качестве дополнительного параметра value того же типа, что и индексатор.

Следует отметить, что доступ к индексатору осуществляется посредством сигнатуры, в отличие от свойства, доступ к которому осуществляется посредством имени. Сигнатурой индексатора считаются число и тип формальных параметров. Тип самого индексатора и имена параметров в сигнатуру не входят. Естественно, в классе не может быть двух индексаторов с одинаковой сигнатурой. К тому же, индексатор не считается переменной и не может быть передан в качестве ref или out параметра.

Индексаторы дают возможность вашим классам использовать их как массивы. Внутри класса вы управляете данными, как вам захочется. Несмотря на внутреннюю реализации класса, эти данные могут быть получены через последовательность с использованием индексаторов.

 

using System;

using System.Collections;

using System.Collections.Generic;

namespace IndexatorSimple

{

class Program

{

class Person

{

public string Name { get; set; }

public string Surname { get; set; }

public int Age { get; set; }

public ArrayList arPeople = new ArrayList();

public Person this[int index]

{

get { return (Person)arPeople[index]; }

set { arPeople.Insert(index, value); }

}

}

static void Main(string[] args)

{

Person person = new Person();

person[0] = new Person { Name = "John", Surname = "Lenon", Age = 53 };

person[1] = new Person { Name = "Ashly", Surname = "Menoton", Age = 27 };

Person p1 = new Person { Name = "Pol", Surname = "Sarmey", Age = 18 };

person[2] = p1;

for (int i = 0; i < 3; i++)

{

Console.WriteLine("{0} {1} {2}", person[i].Name, person[i].Surname,

person[i].Age);

}

Console.ReadLine();

}

}

}

Сначала определяется класс Person в котором объявлены три свойства Name, Surname и Age, потом объявляется список arPeople типа ArrayList. Следующий член класса и есть индексатор, который определен с ключевым словом this и квадратными скобками

public Person this[int index].

Метод принимает единственный параметр позиции - index. Как вы уже видите реализация индексатора такая же, как у свойств.

В Main() объявляется объект person, потом с помощью индексатора добавляются члены к этому объекту. Вывод результата в консоль такой.

John Lenon 53Ashly Menoton 27Pol Sarmey 18

 

В качестве аргумента индексатора может быть не только переменная типа int, но и любой другой тип.

using System;

using System.Collections;

using System.Collections.Generic;

namespace IndexatorSimple

{

class Program

{

class Person

{

public string Name { get; set; }

public string Surname { get; set; }

public int Age { get; set; }

public Dictionary arPeople = new Dictionary();

public Person this[string name]

{

get { return arPeople[name]; }

set { arPeople[name] = value; }

}

}

static void Main(string[] args)

{

Person person = new Person();

person["John"] = new Person {Name="John", Surname = "Lenon", Age = 53 };

person["Ashly"] = new Person {Name="Ashly", Surname = "Menoton",

Age = 27 };

Person p1 = new Person {Name="Pol", Surname = "Sarmey", Age = 18 };

person["Pol"] = p1;

string[] names = new string[] { "John", "Ashly", "Pol" };

for (int i = 0; i < names.Length; i++)

{

Console.WriteLine("{0} {1} {2}", person[names[i]].Name,

person[names[i]].Surname, person[names[i]].Age);

}

Console.ReadLine();

}

}

}

4. Расширение класса путем создания производного класса. Термин «наследование». Существование «прародителя» всех классов. Перекрытие элементов класса в производных классах. Совместимость объектов различных классов. Контроль и преобразование типов. Информация о типе времени выполнения программы.

 



Поделиться:


Последнее изменение этой страницы: 2016-08-14; просмотров: 327; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.145.40.234 (0.006 с.)