Студопедия

КАТЕГОРИИ:

АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

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




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

производные классы. Базовый и производный классы иногда называют суперклассом и подклассом. Эти термины пришли из программирования на языке 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, соответст-

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

Использование ключевого слова base для доступа к скрытому имени

Существует вторая форма использования ключевого слова base, которая действует

подобно ссылке t h i s , за исключением того, что ссылка base всегда указывает на ба-

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

ее записи такой:

base.член

Здесь в качестве элемента член можно указывать либо метод, либо переменную

экземпляра. Эта форма ссылки base наиболее применима в тех случаях, когда имя

члена в производном классе скрывает член с таким же именем в базовом классе. Рас-

смотрим следующую версию иерархии классов из предыдущего примера:

// Использование ссылки base для доступа к скрытому имени.

using System;

class A {

public int i = 0;

}

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

class В : А {

new int i; // Эта переменная i скрывает i класса А.

public В(int a, int b) { !

base.i = а; // Так можно обратиться к i класса А.

i = b; // Переменная i в классе В.

}

public void show() {

// Эта инструкция отображает переменную i в классе А.

Console.WriteLine("i в базовом классе: " + base.i);

// Эта инструкция отображает переменную i в классе В.

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

class UncoverName {

public static void Main() {

В ob = new В(1f 2 );

ob.show();

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

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

Несмотря на то что переменная экземпляра i в классе В скрывает переменную i в

классе А, ссылка base позволяет получить доступ к i в базовом классе.

С помощью ссылки base также можно вызывать скрытые методы.










Последнее изменение этой страницы: 2018-05-27; просмотров: 181.

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