- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
C# 4.0 полное руководство - 2011 - Герберт Шилдт
Шрифт:
Интервал:
Закладка:
Аналогично состоянию public и private, состояние protected сохраняется за членом класса независимо от количества уровней наследования. Поэтому когда производный класс используется в качестве базового для другого производного класса, любой защищенный член исходного базового класса, наследуемый первым производным классом, наследуется как защищенный и вторым производным классом.
Несмотря на всю свою полезность, защищенный доступ пригоден далеко не для всех ситуаций. Так, в классе TwoDShape из приведенного ранее примера требовалось, чтобы значения его членов Width и Height были доступными открыто, поскольку нужно было управлять значениями, которые им присваивались, что было бы невозможно, если бы они были объявлены как protected. В данном случае более подходящим решением оказалось применение свойств, чтобы управлять доступом, а не предотвращать его. Таким образом, модификатор доступа protected следует применять в том случае, если требуется создать член класса, доступный для всей иерархии классов, но для остального кода он должен быть закрытым. А для управления доступом к значению члена класса лучше воспользоваться свойством.
Конструкторы и наследование
В иерархии классов допускается, чтобы у базовых и производных классов были свои собственные конструкторы. В связи с этим возникает следующий резонный вопрос: какой конструктор отвечает за построение объекта производного класса: конструктор базового класса, конструктор производного класса или же оба? На этот вопрос можно ответить так: конструктор базового класса конструирует базовую часть объекта, а конструктор производного класса — производную часть этого объекта. И в этом есть своя логика, поскольку базовому классу неизвестны и недоступны любые элементы производного класса, а значит, их конструирование должно происходить раздельно. В приведенных выше примерах данный вопрос не возникал, поскольку они опирались на автоматическое создание конструкторов, используемых в C# по умолчанию. Но на практике конструкторы определяются в большинстве классов. Ниже будет показано, каким образом разрешается подобная ситуация.
Если конструктор определен только в производном классе, то все происходит очень просто: конструируется объект производного класса, а базовая часть объекта автоматически конструируется его конструктором, используемым по умолчанию. В качестве примера ниже приведен переработанный вариант класса Triangle, в котором определяется конструктор, а член Style делается закрытым, так как теперь он устанавливается конструктором.
// Добавить конструктор в класс Triangle, using System;
11 Класс для двумерных объектов. •
class TwoDShape { double pri_width; double pr.i_height;
// Свойства ширины и длины объекта, public double Width {
get { return pri_width; }
set { pri_width = value < 0 ? -value : value; }
}
public double Height {
get { return pri_height; }
set { pri_height = value < 0 ? -value : value; }
}
public void ShowDim() {
Console.WriteLine("Ширина и длина равны " +
Width + " и " + Height);
}
}
// Класс для треугольников, производный от класса TwoDShape. class Triangle : TwoDShape { string Style;
// Конструктор.
public Triangle(string s, double w, double h) {
Width = w; // инициализировать член базового класса Height = h; // инициализировать член базового класса Style = s; // инициализировать член производного класса
}
// Возвратить площадь треугольника, public double Area() {
return Width * Height / 2;
}
// Показать тип треугольника, public void ShowStyle() {
Console.WriteLine("Треугольник " + Style);
}
}
class Shapes3 {
static void Main() {
Triangle tl = new Triangle("равнобедренный", 4.0, 4.0); Triangle t2 = new Triangle("прямоугольный", 8.0, 12.0);
Console.WriteLine("Сведения об объекте tl: "); tl.ShowStyle(); tl.ShowDim();
Console . WriteLine ("Площадь равна " + tl.AreaO);
Console.WriteLine ();
Console.WriteLine("Сведения об объекте t2: "); t2.ShowStyle(); t2 .-ShowDim () ;
Console.WriteLine("Площадь равна " + t2.Area());
}
}
В данном примере конструктор класса Triangle инициализирует наследуемые члены класса TwoDShape вместе с его собственным полем Style.
Когда конструкторы определяются как в базовом, так и в производном классе, процесс построения объекта несколько усложняется, поскольку должны выполняться конструкторы обоих классов. В данном случае приходится обращаться к еще одному ключевому слову языка С#: base, которое находит двоякое применение: во-первых, для вызова конструктора базового класса; и во-вторых, для доступа к члену базового класса, скрывающегося за членом производного класса. Ниже будет рассмотрено первое применение ключевого слова base.
Вызов конструкторов базового класса
С помощью формы расширенного объявления конструктора производного класса и ключевого слова base в производном классе может быть вызван конструктор, определенный в его базовом классе. Ниже приведена общая форма этого расширенного объявления:
конструктор_производного_класса{список_параметров) : base (список_аргументов) { // тело конструктора
}
где список_аргументов обозначает любые аргументы, необходимые конструктору в базовом классе. Обратите внимание на местоположение двоеточия.
Для того чтобы продемонстрировать применение ключевого слова base на конкретном примере, рассмотрим еще один вариант класса TwoDShape в приведенной ниже программе. В данном примере определяется конструктор, инициализирующий свойства Width и Height. Затем этот конструктор вызывается конструктором класса Triangle.
// Добавить конструктор в класс TwoDShape. using System;
// Класс для двумерных объектов, class TwoDShape { double pri_width; double pri_height;
// Конструктор класса TwoDShape. public TwoDShape(double w, double h) {
Width = w;
Height = h;
}
public double Width {
get { return pri_width; }
set { pri_width = value < 0 ? -value : value; }
}
public double Height {
get { return pri_height; }
set { pri_height = value < 0 ? -value : value; }
}
public void ShowDim() {
Console.WriteLine("Ширина и высота равны " +
Width + " и " + Height);
}
}
// Класс для треугольников, производный от класса TwoDShape. class Triangle : TwoDShape { string Style;
// Вызвать конструктор базового класса.
public Triangle(string s, double w, double h) : base(w, h) Style = s;
}
// Возвратить площадь треугольника, public double Area() {
return Width * Height / 2;
}
// Показать тип треугольника, public void ShowStyleO {
Console.WriteLine("Треугольник " + Style);
}
}
class Shapes4 {
static void Main() {
Triangle tl = new Triangle("равнобедренный", 4.0, 4.0); Triangle t2 = new Triangle("прямоугольный", 8.0, 12.0); Console.WriteLine("Сведения об объекте tl: "); tl.ShowStyle(); tl.ShowDim();
Console.WriteLine("Площадь равна " + tl.AreaO);
Console.WriteLine();
Console.WriteLine("Сведения об объекте t2: "); t2.ShowStyle(); t2.ShowDim();
Console.WriteLine("Площадь равна " + t2.Area());
Теперь конструктор класса Triangle объявляется следующим образом.
public Triangle(
string s, double w, double h) : base(w, h) {
В данном варианте конструктор Triangle () вызывает метод base с параметрами w и h. Это, в свою очередь, приводит к вызову конструктора TwoDShape (), инициализирующего свойства Width и Height значениями параметров w и h. Они больше не инициализируются средствами самого класса Triangle, где теперь остается инициализировать только его собственный член Style, определяющий тип треугольника. Благодаря этому класс TwoDShape высвобождается для конструирования своего по-добъекта любым избранным способом. Более того, в класс TwoDShape можно ввести функции, о которых даже не будут подозревать производные классы, что предотвращает нарушение существующего кода.
С помощью ключевого слова base можно вызвать конструктор любой формы, определяемой в базовом классе, причем выполняться будет лишь тот конструктор, параметры которого соответствуют переданным аргументам. В качестве примера ниже приведены расширенные варианты классов TwoDShape и Triangle, в которые включены как используемые по умолчанию конструкторы, так и конструкторы, принимающие один аргумент.

