Доступ к элементам суперкласса — КиберПедия 

Механическое удерживание земляных масс: Механическое удерживание земляных масс на склоне обеспечивают контрфорсными сооружениями различных конструкций...

История развития хранилищ для нефти: Первые склады нефти появились в XVII веке. Они представляли собой землянные ямы-амбара глубиной 4…5 м...

Доступ к элементам суперкласса

2019-08-04 214
Доступ к элементам суперкласса 0.00 из 5.00 0 оценок
Заказать работу

Не все члены суперкласса наследуются в подклассе. Наследование не распространяется на закрытые члены суперкласса. Другими словами, в подклассе закрытые члены суперкласса недоступны. Напомним, что закрытые члены класса объявляются с ключевым словом 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 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.016 с.