Студопедия КАТЕГОРИИ: АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Закрытый член класса остается закрытым в рамках этого класса. К нему
Нельзя получить доступ из кода, определенного вне этого класса, включая производные классы. Базовый и производный классы иногда называют суперклассом и подклассом. Эти термины пришли из программирования на языке 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 не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда... |