Закрытый член класса остается закрытым в рамках этого класса. К нему



Нельзя получить доступ из кода, определенного вне этого класса, включая

производные классы. Базовый и производный классы иногда называют суперклассом и подклассом. Эти термины пришли из программирования на языке Java. Суперкласс в Java — это базовый класс в С#. Подкласс в Java — это производный класс в С#. Вероятно, вам при-

ходилось слышать эти термины, но мы будем придерживаться стандартных С#-

терминов. В C++ также используются термины "базовый класс/производный класс".

Использование защищенного доступа

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

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

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

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

иногда нежелательно. К счастью, таких ситуаций можно избежать, поскольку С# по-

зволяет создавать защищенные члены. Защищенным является член, который открыт для

своей иерархии классов, но закрыт вне этой иерархии.

Защищенный член создается с помощью модификатора доступа protected. При

объявлении protected-члена он по сути является закрытым, но с одним исключени-

ем. Это исключение вступает в силу, когда защищенный член наследуется. В этом

случае защищенный член базового класса становится защищенным членом производ-

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

используя модификатор доступа protected, можно создавать закрытые (для "внеш-

него мира") члены класса, но вместе с тем они будут наследоваться с возможностью

доступа со стороны производных классов.

Конструкторы и наследование

В иерархии классов как базовые, так и производные классы могут иметь собствен-

ные конструкторы. При этом возникает важный вопрос: какой конструктор отвечает

за создание объекта производного класса? Конструктор базового или конструктор

производного класса, или оба одновременно? Ответ таков: конструктор базового клас-

са создает часть объекта, соответствующую базовому классу, а конструктор производ-

ного класса — часть объекта, соответствующую производному классу. И это вполне

логично, потому что базовый класс "не видит" или не имеет доступа к элементам

производного класса. Поэтому их конструкции должны быть раздельными. В преды-

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

томатически средствами С#, и поэтому мы не сталкивались с подобной проблемой.

Но на практике большинство классов имеет конструкторы, и вы должны знать, как

справляться с подобной ситуацией.

Если конструктор определяется только в производном классе, процесс создания

объекта несложен: просто создается объект производного класса. Часть объекта, соот-

ветствующая базовому классу, создается автоматически с помощью конструктора по

умолчанию.

Наследование и сокрытие имен

Производный класс может определить член, имя которого совпадает с именем

члена базового класса. В этом случае член базового класса становится скрытым в про-

изводном классе. Поскольку с точки зрения формального синтаксиса языка С# эта

ситуация не является ошибочной, компилятор выразит свое "недоумение" всего лишь

предупреждающим сообщением. Это предупреждение должно послужить напомина-

нием о факте сокрытия имени. Если вы действительно собирались скрыть член базо-

вого класса, то для предотвращения этого предупреждения перед членом произвол-

ного класса необходимо поставить ключевое слово new. Необходимо понимать, что

эта функция слова new совершенно отличается от его использования при создании

экземпляра объекта.

Рассмотрим пример сокрытия имени.

// Пример сокрытия имени в связи с наследованием.

using System;

class A {

public int i = 0;

}

// Создаем производный класс,

class В : А {

new int i; // Этот член i скрывает член i класса А.

public В(int b) {

i = b; // Член i в классе В.

public void show() {

Console.WriteLine(

"Член i в производном классе: " + i);

class NameHiding {

public s t a t i c void Main() {

В ob = new В(2);

ob.show();

Во-первых, обратите внимание на использование ключевого слова new при объяв-

лении члена i в классе в. По сути, он сообщает компилятору о том, что вы знаете,

что создается новая переменная с именем i, которая скрывает переменную i в базо-

вом классе А. Если убрать слово new, компилятор сгенерирует предупреждающее со-

общение.

Результаты выполнения этой программы выглядят так: /

I Член i в производном классе: 2

Поскольку в классе в определяется собственная переменная экземпляра с именем

i , она скрывает переменную i, определенную в классе А. Следовательно, при вызове

метода show() для объекта типа в, отображается значение переменной i, соответст-

вующее ее определению в классе В, а не в классе А.


Дата добавления: 2018-05-13; просмотров: 381; Мы поможем в написании вашей работы!

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






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