Чтение онлайн

ЖАНРЫ

Язык программирования C#9 и платформа .NET5
Шрифт:

_currSpeed = 10;

}

}

Замечание относительно множества базовых классов

Говоря о базовых классах, важно иметь в виду, что язык C# требует, чтобы отдельно взятый класс имел в точности один непосредственный базовый класс. Создать тип класса, который был бы производным напрямую от двух и более базовых классов, невозможно (такой прием, поддерживаемый в неуправляемом языке C++, известен как множественное наследование). Попытка создать класс, для которого указаны два непосредственных родительских класса, как продемонстрировано в следующем коде, приведет к ошибке на этапе компиляции:

//
Недопустимо! Множественное наследование

// классов в языке C# не разрешено!

class WontWork

: BaseClassOne, BaseClassTwo

{}

В главе 8 вы увидите, что платформа .NET Core позволяет классу или структуре реализовывать любое количество дискретных интерфейсов. Таким способом тип C# может поддерживать несколько линий поведения, одновременно избегая сложностей, которые связаны с множественным наследованием. Применяя этот подход, можно строить развитые иерархии интерфейсов, которые моделируют сложные линии поведения (см. главу 8).

Использование ключевого слова sealed

Язык C# предлагает еще одно ключевое слово,

sealed
, которое предотвращает наследование. Когда класс помечен как
sealed
(запечатанный), компилятор не позволяет создавать классы, производные от него. Например, пусть вы приняли решение о том, что дальнейшее расширение класса
MiniVan
не имеет смысла:

// Класс Minivan не может быть расширен!

sealed class MiniVan : Car

{

}

Если вы или ваш коллега попытаетесь унаследовать от запечатанного класса

MiniVan
, то получите ошибку на этапе компиляции:

// Ошибка! Нельзя расширять класс, помеченный ключевым словом sealed!

class DeluxeMiniVan

: MiniVan

{

}

Запечатывание класса чаще всего имеет наибольший смысл при проектировании обслуживающего класса. Скажем, в пространстве имен

System
определены многочисленные запечатанные классы, такие как
String
. Таким образом, как и в случае
MiniVan
, если вы попытаетесь построить новый класс, который расширял бы
System.String
, то получите ошибку на этапе компиляции:

// Еще одна ошибка! Нельзя расширять класс, помеченный как sealed!

class MyString

: String

{

}

На заметку! В главе 4 вы узнали о том, что структуры C# всегда неявно запечатаны (см. табл. 4.3). Следовательно, создать структуру, производную от другой структуры, класс, производный от структуры, или структуру, производную от класса, невозможно. Структуры могут применяться для моделирования только отдельных, атомарных, определяемых пользователем типов. Если вы хотите задействовать отношение "является", тогда должны использовать классы.

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

sealed
предотвращает последующее наследование.

Еще раз о диаграммах классов Visual Studio

В главе 2 кратко упоминалось о том, что среда Visual Studio позволяет устанавливать отношения "базовый-производный" между классами визуальным образом во время проектирования. Для работы с указанным аспектом IDE-среды сначала понадобится

добавить в текущий проект новый файл диаграммы классов. Выберите пункт меню Project?Add New Item (Проект?Добавить новый элемент) и щелкните на значке Class Diagram (Диаграмма классов); на рис. 6.1 видно, что файл был переименован с
ClassDiagraml.cd
на
Cars.cd
.

После щелчка на кнопке Add (Добавить) отобразится пустая поверхность проектирования. Чтобы добавить типы в визуальный конструктор классов, просто перетаскивайте на эту поверхность каждый файл из окна Solution Explorer (Проводник решений). Также вспомните, что удаление элемента из визуального конструктора (путем его выбора и нажатия клавиши <Delete>) не приводит к уничтожению ассоциированного с ним исходного кода, а просто убирает элемент из поверхности конструктора. Текущая иерархия классов показана на рис. 6.2.

Как говорилось в главе 2. помимо простого отображения отношений между типами внутри текущего приложения можно также создавать новые типы и наполнять их членами, применяя панель инструментов конструктора классов и окно Class Details (Детали класса).

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

Второй принцип объектно-ориентированного программирования: детали наследования

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

Employee
, который был спроектирован в главе 5. Первым делом создайте новый проект консольного приложения C# по имени
Employees
.

Далее скопируйте в проект

Employees
файлы
Employee.cs
,
Employee.Core.cs
и
EmployeePayTypeEnum.cs
, созданные ранее в проекте
EmployeeApp
из главы 5.

На заметку! До выхода .NET Core, чтобы использовать файлы в проекте С#, на них необходимо было ссылаться в файле

.csproj
. В версии .NET Core все файлы из текущей структуры каталогов автоматически включаются в проект. Простого копирования нескольких файлов из другого проекта достаточно для их включения в ваш проект.

Прежде чем приступать к построению каких-то производных классов, следует уделить внимание одной детали. Поскольку первоначальный класс

Employee
был создан в проекте по имени
EmployeeApp
, он находится внутри идентично названного пространства имен .NET Core. Пространства имен подробно рассматриваются в главе 16; тем не менее, ради простоты переименуйте текущее пространство имен (в обоих файлах) на
Employees
, чтобы оно совпадало с именем нового проекта:

// Не забудьте изменить название пространства имен в обоих файлах С#!

namespace Employees

{

partial class Employee

{...}

}

На заметку! Если вы удалили стандартный конструктор во время внесения изменений в код класса

Employee
в главе 5, тогда снова добавьте его в класс.

Вторая деталь касается удаления любого закомментированного кода из различных итераций класса

Employee
, рассмотренных в примере главы 5.

Поделиться с друзьями: