
- •Глава 10, описывающая классы как контейнеры их статических членов,
- •Глава 13 посвящена отношениям между классами (и их объектами). Особое
- •Глава 18 включена в книгу при подготовке второго издания. Она посвящен
- •Глава 1. Объектная ориентация программ
- •1.1. Типы, классы, объекты
- •1.2. Программа на c#
- •1.3. Пространство имен
- •1.4. Создание консольного приложения
- •Глава 2. Типы в языке c#
- •2.1. Типы ссылок и типы значений
- •2.2. Классификация типов c#
- •2.3. Простые типы. Константы-литерал
- •2.4. Объявления переменных и констант базовых типо
- •If implicit in int interface
- •Internal is lock long namespace
- •Volatile while
- •Глава 3. Операции и целочисленные выражения
- •3.1. Операции языка c#
- •3.2. Операции присваивания и оператор
- •3.4. Выражения с арифметическими операциями
- •3.6. Переполнения при операциях с целыми
- •Глава 4. Выражения с операндами базовых
- •4.1. Автоматическое и явное приведение арифметических типов
- •4.2. Особые ситуации в арифметических выражениях
- •4.3. Логический тип и логические выражения
- •4.4. Выражения с символьными операндами
- •4.5. Тернарная (условная) операция
- •Глава 5. Типы с# как классы платформы .Net
- •5.1. Платформа .Net Framework и спецификация cts
- •5.2. Простые (базовые) типы c# как классы
- •5.3. Специфические методы и поля простых типов
- •Глава 6. Операторы
- •6.1. Общие сведения об операторах
- •6.2. Метки и оператор безусловного перехода
- •6.3. Условный оператор (ветвлений)
- •If (логическое выражение) оператор_1
- •6.4. Операторы цикла
- •6.5. Операторы передачи управления
- •If (условие) break;
- •6.6. Переключатель
- •Int ball; // оценка в баллах:
- •Глава 7. Массивы
- •7.1. Одномерные массивы
- •Int [ ] integers
- •Int number;
- •7.2. Массивы как наследники класса Array
- •7.3. Виды массивов и массивы многомерные
- •Int [,] dots;
- •Int size;
- •7.4. Массивы массивов и непрямоугольные массивы
- •Int size;
- •7.5. Массивы массивов и поверхностное копирование
- •Int size;
- •Int size;
- •Глава 8. Строки – объекты класса string
- •8.1. Строковые литералы
- •8.2. Строковые объекты и ссылки типа string
- •242.ToString()
- •8.3. Операции над строками
- •8.4. Некоторые методы и свойства класса String
- •8.5. Форматирование строк
- •8.6. Строка как контейне
- •8.7. Применение строк в переключателях
- •8.8. Массивы строк
- •8.8. Сравнение строк
- •Int static Compare (string, string)
- •Int static Compare (string, string, Boolean,CultureInfo)
- •If (string.Compare(res, hen, true,
- •8.9. Преобразования с участием строкового типа
- •38 Попугаев.
- •8.10. Аргументы метода Main( )
- •8.11. Неизменяемость объектов класса String
- •Глава 9. Методы c#
- •9.1. Методы–процедуры и методы-функции
- •9.2. Соотношение фиксированных параметров и аргументов
- •Int iPart;
- •9.3. Параметры с типами ссылок
- •Int[ ] temp;
- •Int[ ] temp;
- •9.4. Методы с переменным числом аргументов
- •VarParams(a, b, c);
- •9.5. Перегрузка методов
- •9.6. Рекурсивные методы
- •4*Fact (3); {
- •9.7. Применение метода Array.Sort()
- •Int имя_функции(тип параметр_1, тип параметр_2)
- •If(условие 2) return -1; // порядок соблюдён
- •Глава 10. Класс как совокупность статических
- •10.1. Статические члены класса
- •10.2. Поля классов (статические поля)
- •Int X; // поле объектов класса
- •10.3. Статические константы
- •10.4. Статические методы
- •10.5. Статический конструктор
- •10.6. Статические классы
- •Глава 11. Классы как типы
- •11.1. Объявление класса
- •11.2. Поля объектов
- •11.3. Объявления методов объектов
- •11.4. Пример класса и его объектов
- •Int count; // текущее показание
- •1 ' Counter.Count' is inaccessible due to its protection leve
- •11.5. Ссылка this
- •Int numb;
- •11.6. Конструкторы объектов класса
- •Int p; // порядок - инициализация по умолчанию
- •Void reduce() // Приведение числа к каноническому виду.
- •11.7. Деструкторы и финализаторы
- •Глава 12. Средства взаимодействия с объектами
- •12.1. Принцип инкапсуляции и методы объектов
- •12.2. Свойства классов
- •Internal, private, static, virtual, sealed, override, abstract, extern
- •Internal protected
- •Int p; // инициализация по умолчанию
- •Void reduce() // "Внутренний" для класса метод
- •12.3. Автореализуемые свойств
- •12.4. Индексаторы
- •Int[] days; // часы по дням недели
- •Int search(string str) { // поиск слова
- •12.5. Индексаторы, имитирующие наличие контейнера
- •Глава 13. Включение, вложение и наследование
- •13.1. Включение объектов классов
- •13.2. Вложение классов
- •13.3. Наследование классов
- •13.4. Доступность членов класса при наследовании
- •13.5. Методы при наследовании
- •13.6. Абстрактные методы и абстрактные классы
- •13.7. Опечатанные классы и методы
- •13.8. Применение абстрактых классов
- •Глава 14. Интерфейсы
- •14.1. Два вида наследования в ооп
- •14.2. Объявления интерфейсов
- •Interface имя_интерфейса
- •Interface iPublication { // интерфейс публикаций
- •Void write(); // готовить публикацию
- •Void read(); // читать публикацию
- •14.3. Реализация интерфейсов
- •Interface iPublication { // интерфейс публикаций
- •Void write(); // готовить публикацию
- •Void read(); // читать публикацию
- •Interface iSeries {
- •Void setBegin(); // восстановить начальное состояние
- •Int GetNext { get; } // вернуть очередной член ряда
- •Int this[int k] {get;} // вернуть к-й член ряда
- •Interface iSeries // интерфейс числовых рядов
- •14.4. Интерфейс как ти
- •Interface iGeo { // интерфейс геометрической фигуры
- •Void transform(double coef); // преобразовать размеры
- •Void display(); // вывести характеристики
- •Interface iGeo {
- •Void transform(double coef); // преобразовать размеры
- •Void display(); // вывести характеристики
- •Ira.Transform(3);
- •Ira.Transform(3);
- •14.5. Интерфейсы и наследование
- •Interface iPublication // интерфейс публикаций
- •Interface iBase
- •Interface iBase {
- •Глава 15. Перечисления и структуры
- •15.1. Перечисления
- •15.2. Базовый класс перечислений
- •IsDe fined"
- •15.3. Структуры
- •15.4. Упаковка и распаковка
- •If (obj is Struct1)
- •If (ob is PointS)
- •If (ob is Double)
- •15.5. Реализация структурами интерфейсов
- •Interface iShape {
- •Interface iShape
- •Information(ci);
- •Information(sp);
- •Interface iImage {
- •Void display();
- •Interface iImage
- •Void display();
- •Глава 16. Исключения
- •16.1. О механизме исключений
- •16.3. Свойства исключений
- •16.4. Управление программой с помощью исключений
- •X; // Вводимое число.
- •16.5. Исключения в арифметических выражениях
- •16.6. Генерация исключений
- •If (!double.TryParse(input, out u))
- •If (!double.TryParse(input, out u)
- •16.7. Пользовательские классы исключений
- •Глава 17. Делегаты и события
- •17.1. Синтаксис делегатов
- •17.2. Массивы делегатов
- •Int X, y; // положение робота на плоскости
- •17.3. Многоадресные (групповые) экземпляры делегатов
- •Virtual
- •17.4. Делегаты и обратные вызовы
- •17.5. Анонимные методы
- •17.6. События
- •Int size; // размер массива
- •Int[ ] ar; // ссылка на массив
- •Int temp;
- •Глава 18. Обобщения
- •18.1. Обобщения как средство абстракции
- •18.2. Декларации обобщённых классов "декларация
- •18.3. Ограничения типизирующих параметров
- •Intemface iComparable {
- •Int CompareTo (object p);
- •18.4. Обобщённые структуры "обобщённые структуры"
- •18.5. Обобщённые интерфейсы "обобщённый интерфейс"
- •Int add(t X, t y); // прототип метода
- •18.6. Обобщённые методы "обобщённые методы"
- •18.7. Обобщённые делегаты "обобщённые делегаты"
- •Virtual
- •InnerException
- •Interface
Internal protected
Тело аксессора это либо блок, либо пустой оператор, обозначаемый символом
точка с запятой. Пустой оператор в качестве тела применяется для аксессоров тех
свойств, которые объявлены с модификаторами abstract и extern. Сейчас такие
свойства мы не рассматриваем.
Аксессор доступа
"аксессор доступа"
(get-аксессор) – подобен методу без
параметров, возвращающему значение, тип которого определяется типом свойства.
Достаточно часто аксессор доступа возвращает значение конкретного поля класса
или его объекта. Для возврата значения из аксессора в его теле должен выполниться
оператор
return выражение;
Аксессор изменения "аксессор изменения" (set-аксессор) – подобен методу с
возвращаемым значением типа void и единственным неявно заданным параметром,
значение которого определяет новое значение свойства. Тип параметра определяется
типом свойства. Имя параметра, которое используется в теле аксессора изменений,
всегда value.
В теле аксессоров свойства могут быть сложные алгоритмы обработки.
Например, при изменении свойства можно контролировать диапазон допустимых
значений. В теле аксессора доступа возвращаемое значение может вычисляться с
учетом значений не одного, а разных полей, и т.д.. Часто свойство используют для
работы с одним закрытым полем класса. Заметим, что и при таком использовани
и
свойство не вводит новых полей, а только управляет доступом к уже
существующим в классе полям. Существует соглашение (не обязательное) начинать
имена свойств с заглавных букв. Если свойство представляет "во внешнем мире"
конкретное поле класса, то имя свойства повторяет имя поле, но отличается от него
первой заглавной буквой. Например, если в классе объявлено поле tempor, то
представляющее его свойство рекомендуется назвать Tempor.
Пример класса чисел в научной нотации со свойствами (12_02.cs):
class Real // Класс чисел в научной нотации
{ // Закрытые поля:
double m = 8.0; // мантисса - явно инициализирована
Int p; // инициализация по умолчанию
// свойство для получения значения мантиссы:
public double Mantissa
{
get { return m; }
}
// свойство для показателя:
public int Exponent
{
get { return p; }
set { p = value; }
}
// свойство для значения числа:
public double RealValue
{
get { return m * Math.Pow(10, p); }
set { m = value; p = 0;
reduce();
}
}
Void reduce() // "Внутренний" для класса метод
{
double sign = 1; if (m < 0) {sign = -1; m = -m; }
for (; m >= 10; m /= 10, p += 1) ;
for (; m < 1; m *= 10, p -= 1) ;
m *= sign;
}
}
В классе Real уже рассмотренные закрытые члены: вспомогательный метод
reduce(), поля double m – мантисса, int p – показатель. Кроме того, объявлены три
открытых свойства:
public double Mantissa – для получения значения мантиссы;
public int Exponent – для получения и изменения показателя;
public double RealValue – для получения числа в виде значения вещественного
типа и для задания значений полей объекта по значению типа double.
В определении свойства Mantissa только один аксессор get, он позволяет
получить значение поля double m.
Свойство Exponent включает два аксессора:
set { p = value; } – изменяет значение поля int p;
get { return p; } – возвращает значение того же поля.
Свойство RealValue позволяет обратиться к объекту класса Real как к
числовому значению типа double. Аксессоры свойства:
get { return m * Math.Pow(10, p); }
set { m = value; p = 0; reduce(); }
Аксессор get возвращает числовое значение, вычисленное на основе значений
полей объекта.
Аксессор set, получив из внешнего обращения значение value, присваивает его
переменной поля double m. При этом переменная int p получает нулевое значение.
Затем для приведения числа к научной нотации в теле аксессора выполняется
обращение к вспомогательному методу класса reduce(). Его мы уже рассмотрели в
связи с обсуждением конструкторов.
Следующий фрагмент кода иллюстрирует применение свойств класса
(программа 12_02.cs):
static void Main()
{
Real number = new Real(); // конструктор умолчания
string form = " = {0,8:F5} * 10^{1,-3:D2}";
Console.WriteLine("number" + form,
number.Mantissa, number.Exponent);
number.Exponent = 2;
Console.WriteLine("number" + form,
number.Mantissa, number.Exponent);
Console.WriteLine("number RealValue = " + number.RealValue);
number.RealValue = -314.159;
Console.WriteLine("number" + form,
number.Mantissa, number.Exponent);
Console.WriteLine("number RealValue = " + number.RealValue);
}
В программе с помощью конструктора умолчания Real() определен один
объект
класса
чисел
в
научной
нотации
и
объявлена
ссылка
number,
ассоциированная с этим объектом. Дальнейшие манипуляции с объектом
выполнены с помощью свойств Mantissa, Exponent, RealValue. Для обращения к ним
используются уточненные имена вида имя_объекта.имя_свойства.
Результат выполнения программы:
number = 8,00000 * 10^00
number = 8,00000 * 10^02
number RealValue = 800
number = -3,14159 * 10^02
number RealValue = -314,159
В первой строке результатов приведено изображение числа из объекта,
созданного конструктором умолчания. Значения полей при выводе получены с
помощью уточненных имён свойств number.Mantissa, number.Exponent.
Оператор number.Exponent = 2; через свойство Exponent изменяет значение
поля показателя int p. Этим определяется вторая строка результатов выполнения
программы.
В третьей строке – числовое значение объекта number, полученное с помощью
свойства RealValue.
Оператор
number.RealValue = -314.159; через свойство RealValue изменяет
оба поля объекта number.
Результат изменения полей иллюстрирует предпоследняя строка результатов.
В последней строке – значение свойства RealValue.
Аксессор get выполняется, когда из кода, внешнего по отношению к классу или
его объекту, выполняется «чтение» значения свойства. При этом в точку вызов
а
возвращается некоторое значение или ссылка на объект. Тип значения или ссылки
соответствует типу в объявлении свойства. При этом возможны неявные
приведения типов. Например, если get-аксессор возвращает значение типа int, а тип
свойства double, то будет автоматически выполнено приведение типов. Get-аксессор
подобен методу без параметров, возвращающему значение или ссылку с типом
свойства.
Если внешний по отношению к классу или его объекту код присваивает
некоторое значение свойству, то вызывается set-аксессор этого свойства. В теле
этого аксессора присвоенное свойству значение представлено специальной
переменной с фиксированным именем value. Тип этой переменной совпадает с типом
свойства. У set-аксессора возвращаемое значение отсутствует. Можно считать, что
set-аксессор функционально подобен методу с одним параметром. У этого
параметра тот же тип, что и тип свойства, и фиксированное имя value.
Можно использовать в объявлении свойства только один из аксессоров. Это
позволяет вводить свойства только для записи (изменения) и свойства только для
чтения. Возникает вопрос, чем открытое свойство, обеспечивающее только чтение,
отличается от открытого поля, объявленного с модификатором readonly. Основное
отличие в том, что поле хранит некоторое значение, которое не может изменить
процесс
чтения из этого поля. При чтении значения свойства есть возможность
выполнить заранее запланированные действия (вычисления), причём никаких
ограничений на характер этих действий (вычислений) не накладывается. Результат
вычислений свойства может зависеть, например, от состояния среды, в которой
выполняется программа, или от влияния процессов, выполняемых параллельно.
Пример поля с модификатором readonly: "дата рождения". Свойство "точный
возраст" должно вычисляться с учётом конкретного момента обращения к этому
свойству.