Механическое удерживание земляных масс: Механическое удерживание земляных масс на склоне обеспечивают контрфорсными сооружениями различных конструкций...
История развития хранилищ для нефти: Первые склады нефти появились в XVII веке. Они представляли собой землянные ямы-амбара глубиной 4…5 м...
Топ:
Оценка эффективности инструментов коммуникационной политики: Внешние коммуникации - обмен информацией между организацией и её внешней средой...
Интересное:
Лечение прогрессирующих форм рака: Одним из наиболее важных достижений экспериментальной химиотерапии опухолей, начатой в 60-х и реализованной в 70-х годах, является...
Аура как энергетическое поле: многослойную ауру человека можно представить себе подобным...
Что нужно делать при лейкемии: Прежде всего, необходимо выяснить, не страдаете ли вы каким-либо душевным недугом...
Дисциплины:
2019-08-04 | 214 |
5.00
из
|
Заказать работу |
|
|
Не все члены суперкласса наследуются в подклассе. Наследование не распространяется на закрытые члены суперкласса. Другими словами, в подклассе закрытые члены суперкласса недоступны. Напомним, что закрытые члены класса объявляются с ключевым словом private, а по умолчанию, если никакое ключевое слово не указано, члены класса считаются открытыми. Именно поэтому, несмотря на отсутствие ключевых слов, описывающих уровень доступа, в рассмотренном примере никаких проблем с наследованием не возникало.
Для иллюстрации того, что происходит при наследовании, когда суперкласс содержит закрытые члены, рассмотрим пример в листинге 2.
Листинг 2. Закрытые члены суперкласса
class MySuperClass{ // Суперкласс
// Закрытое поле:
private int a;
// Закрытый метод:
private void showa(){
System.out.println("Поле a: "+a);}
// Открытый метод:
void seta(int n){
a=n;
showa();}
}
class MySubClass extends MySuperClass{ // Подкласс
int b;
void setall(int i,int j){
seta(i);
b=j;
System.out.println("Поле b: "+b);}
}
class PrivateSuperDemo{
public static void main(String arg[]){
// Объект подкласса:
MySubClass obj=new MySubClass();
obj.setall(1,5);}
}
В результате выполнения этой программы получаем сообщения:
Поле a: 1
Поле b: 5
Рассмотрим подробнее программный код и особенности его выполнения. В первую очередь имеет смысл обратить внимание на суперкласс MySuperClass, в котором описывается закрытое (с идентификатором доступа private) целочисленное поле a и два метода. Закрытый метод showa() предназначен для отображения значения поля a. Открытый метод seta() позволяет присвоить значение закрытому полю a и вывести значение этого поля на экран — для этого в методе seta() вызывается метод showa(). Следовательно, при вызове открытого метода seta() выполняется обращение к закрытому полю a, причем как напрямую, так и через вызов закрытого метода showa().
|
В подклассе MySubClass описывается открытое целочисленное поле b и открытый метод setall(). Кроме того, классом MySubClass из класса MySuperClass наследуется открытый метод seta(). Закрытое поле a и закрытый метод showa() классом MySubClass не наследуются. Ситуация складывается интригующая. Объявленный непосредственно в классе MySubClass метод setall() вызывает, кроме прочего, наследуемый из класса MySuperClass метод seta(), который, в свою очередь, обращается к ненаследуемому полю a и ненаследуемому методу showa(). Может сложиться впечатление, что такой код некорректен, поскольку, например, при вызове метода setall() из объекта obj класса MySubClass делается попытка присвоить и считать значение для поля a, которого в объекте obj в принципе нет. Тем не менее код работает.
Все становится на свои места, если уточнить понятия «наследуется» и «не наследуется». Дело в том, что наследование членов суперкласса подразумевает, что эти поля доступны в подклассе. Другими словами, подкласс «знает» о существовании наследуемых членов, и к этим членам можно обращаться так, как если бы они были описаны в самом классе. Если же член классом не наследуется, то таком члене класс ничего «не знает», и, соответственно, попытка обратиться к такому «неизвестному» для класса члену напрямую ведет к ошибке. Однако технически ненаследуемые члены в классе существуют, о чем свидетельствует хотя бы приведенный пример. Причина кроется в способе создания объектов подкласса. Дело в том, что при создании объекта подкласса сначала вызывается конструктор суперкласса, а затем непосредственно конструктор подкласса. Конструктором суперкласса выделяется в памяти место для всех членов объекта, в том числе и ненаследуемых. Подробнее об этом — в следующем разделе.
Конструкторы и наследование
Если суперкласс и подкласс используют конструкторы по умолчанию (то есть ни в суперклассе, ни в подклассе конструкторы не описаны), то процесс со здания объекта подкласса для программиста проходит обыденно — так же, как создание объекта обычного класса. Ситуация несколько меняется, если конструктору суперкласса необходимо передавать аргументы. Возникает проблема: поскольку при создании объекта подкласса сначала автоматически вызывается конструктор суперкласса, в этот конструктор как-то нужно передать аргументы, даже если непосредственно конструктор подкласса может без них обойтись.
|
Все это накладывает некоторые ограничения на способ описания конструктора подкласса. Формально эти ограничения сводятся к тому, что в конструкторе подкласса необходимо предусмотреть передачу аргументов конструктору суперкласса (разумеется, если такая передача аргументов вообще требуется).
Технически решение проблемы сводится к тому, что в программный код конструктора подкласса добавляется инструкция вызова конструктора суперкласса с указанием аргументов, которые ему передаются. Для этого используется ключевое слово super, после которого в круглых скобках указываются аргументы, передаваемые конструктору суперкласса. Инструкция вызова конструктора суперкласса указывается первой командой в теле конструктора подкласса. Таким образом, общий синтаксис объявления конструктора подкласса имеет следующий вид:
конструктор_подкласса(аргументы1){
super(аргументы2); // аргументы конструктора суперкласса
// тело конструктора подкласса
}
Если в теле конструктора подкласса инструкцию super не указать вовсе, в качестве конструктора суперкласса вызывается конструктор по умолчанию (конструктор без аргументов). Пример описания конструкторов при наследовании приведен в листинге 3.
Листинг 3. Конструкторы и наследование
// Суперкласс:
class MySuperClass{
int a;
void showa(){
System.out.println("Объект с полем a="+a);}
// Конструкторы суперкласса:
MySuperClass(){
a=0;
showa();}
MySuperClass(int i){
a=i;
showa();}
}
// Подкласс:
class MySubClass extends MySuperClass{
double x;
void showx(){
System.out.println("Объект с полем x="+x);}
// Конструкторы подкласса:
MySubClass(){
super(); // Вызов конструктора суперкласса
x=0;
showx();}
MySubClass(int i,double z){
super(i); // Вызов конструктора суперкласса
x=z;
showx();}
}
class SuperConstrDemo{
public static void main(String[] args){
System.out.println("Первый объект:");
MySubClass obj1=new MySubClass();
System.out.println("Второй объект:");
MySubClass obj2=new MySubClass(5,3.2);}
}
В результате выполнения этой программы получаем последовательность сообщений:
|
Первый объект:
Объект с полем a=0
Объект с полем x=0.0
Второй объект:
Объект с полем a=5
Объект с полем x=3.2
Программа состоит из трех классов. В первом классе MySuperClass описано целочисленное поле a, метод showa() для отображения значения этого поля, а также два варианта конструкторов: без аргументов и с одним аргументом. В конструкторе без аргументов полю a присваивается нулевое значение. В конструкторе с аргументом полю присваивается значение аргумента. В обоих случаях с помощью метода showa() значение поля a выводится на экран.
На основе класса MySuperClass создается подкласс MySubClass. Непосредственно в классе описывается поле x типа double и метод showx() для отображения значения этого поля.
В подклассе определяются два конструктора: без аргументов и с двумя аргументами. В каждом из этих конструкторов с помощью инструкции super вызывается конструктор суперкласса. В конструкторе подкласса без аргументов командой super() вызывается конструктор суперкласса без аргументов. Если при создании объекта подкласса конструктору передаются два аргумента (типа int и типа double), то аргумент типа int передается аргументом конструктору суперкласса (командой super(i) в теле конструктора подкласса с двумя аргументами).
В главном методе программы создаются два объекта подкласса MySubClass. В первом случае вызывается конструктор без аргументов, во втором — конструктор с двумя аргументами.
|
|
Архитектура электронного правительства: Единая архитектура – это методологический подход при создании системы управления государства, который строится...
Историки об Елизавете Петровне: Елизавета попала между двумя встречными культурными течениями, воспитывалась среди новых европейских веяний и преданий...
Археология об основании Рима: Новые раскопки проясняют и такой острый дискуссионный вопрос, как дата самого возникновения Рима...
Организация стока поверхностных вод: Наибольшее количество влаги на земном шаре испаряется с поверхности морей и океанов (88‰)...
© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!