- •Создание и инициализация объектов (2)
- •Создание и инициализация объектов (3) Пример
- •Уничтожение объектов
- •Пример объявления классов и работы с объектами (1)
- •Пример объявления классов и работы с объектами (2)
- •Пример объявления классов и работы с объектами (3)
- •Пример объявления классов и работы с объектами (4)
- •Пример объявления классов и работы с объектами (5)
- •Пример объявления классов и работы с объектами (6)
- •Пример объявления классов и работы с объектами (7)
- •Особенности наследования классов в Java (1)
- •Особенности наследования классов в Java (2)
- •Особенности наследования классов в Java (3)
- •Особенности наследования классов в Java (4)
- •Особенности наследования классов в Java (5)
Особенности наследования классов в Java (1)
Если родительский класс не указан, то родителем по умолчанию является класс java.lang.Object.
Не допускается циклическое наследование:
class A extends B { … } |
|
class B extends C { … } |
|
… |
|
class X extends A { … } |
// ошибка |
Не допускается наследование от final класса.
Поля и методы передаются по наследству, конструкторы и инициализаторы – нет.
Если класс имеет поля/методы без модификаторов public, protected, private, то его наследник из того же пакета и
наследник из другого пакета будут иметь доступ к разному набору элементов (полей/методов) родительского класса.
Особенности наследования классов в Java (2)
Затенение (shadowing) полей родительского класса.
Затенением называется объявление в классе-потомке поля с таким же именем, какое имеет поле родительского класса:
class ParentParent { int field;
…
}
class Parent extends ParentParent { short field;
…
}
class Child extends Parent { long field;
…
//доступ к затененным полям из метода класса Child: field += super.field * (( ParentParent ) this ).field ;
//super.super.field - неправильный синтаксис
}
Синтаксис доступа к статическим и динамическим затененным полям одинаков.
Особенности наследования классов в Java (3)
Замещение (overriding) методов родительского класса.
Замещением называется объявление в классе-потомке метода с такой же сигнатурой, какую имеет метод родительского класса. Технология замещения методов класса (статических методов) похожа на технологию затенения полей. Замещение методов экземпляра (объявленных без ключевого слова static) выполняется по другому и не допускает возможности вызова замещенного метода (это и есть механизм виртуальных функций).
Вот пример: class Parent {
int field = 1;
int getField( ) { return field; }
static String getClassName( ) { return "Parent"; }
}
class Child extends Parent { int field = 2;
int getField( ) { return 2 * field; }
static String getClassName( ) { return "Child"; }
}
Здесь затенено поле field и замещены методы getField() (метод экземпляра) и getClassName() (метод класса).
Особенности наследования классов в Java (4)
Вот результаты обращений к полям и вызовов методов экземпляра
подкласса и суперкласса: |
|
Child child = new Child( ); |
// создание экземпляра Child |
System.out.println( child.field ); |
// Результат: 2 |
System.out.println( child.getField( ) ); |
// Результат: 4 |
System.out.println( child.getClassName( ) ); |
// Child |
// а лучше так: Child.getClassName( ) |
|
Parent parent = (Parent) child; |
// приведение к типу Parent |
System.out.println( parent.field ); |
// Результат: 1 |
System.out.println( parent.getField( ) ); |
// Результат: 4 !!! |
|
// переменная parent, |
|
// имея тип Parent, тем не |
|
// менее указывает на объект |
|
// типа Child, из которого и |
|
// берется ссылка на метод |
System.out.println( parent.getClassName( ) ); // Parent // и здесь лучше так: Parent.getClassName( )
Особенности наследования классов в Java (5)
Замещенный метод родительского класса может быть вызван из замещающего метода подкласса путем использования ключевого слова super:
class Parent {
…
int method() { … }
…
}
class Child extends Parent {
…
int method() { … super.method() … }
…
}
Однако синтаксис вида super.super. … () запрещен. Дальше работают механизмы динамического поиска реализации метода с данным именем. Если этот метод действительно реализован в родительском классе, то будет вызван именно он. Иначе он унаследован от какого-либо из родителей и виртуальная машина будет осуществлять перебор этих родителей.
Не могут быть затенены/замещены private и/или final поля/методы. При попытке сделать это компилятор выдаст сообщение об ошибке.
