2013-05-02 4 views
1

Я не совсем уверен, правильно ли сформулировал свой вопрос, но я смущен этими строками кода.super() конструктор внутри подкласса, который расширяет подкласс?

public class First { 
    public String name() { 
     return "First"; 
    } 
} 

public class Second extends First { 
    public void whoRules() { 
     System.out.print(super.name() + " rules"); 
     System.out.println(" but " + name() + " is even better"); 
    } 
    public String name() { 
     return "Second"; 
    } 
} 

public class Third extends Second { 
    public String name() { 
     return "Third"; 
    } 
} 

Second varSecond = new Second(); 
Third varThird = new Third(); 
varSecond.whoRules(); 
varThird.whoRules(); 

Когда выше выполнена, она печатает

First rules but second is even better 

First rules but third is even better 

почему не было бы:

First rules but second is even better 

Second rules but third is even better 

Может подкласс быть суперкласс для другого класса? Или может быть только один (суперкласс)? (Использование примерного кода выше) Я понимаю, что First является суперклассом для Second, но является Second суперклассами для Third? Или First суперкласс для Third?

Если бы было 10 классов, которые простирались друг от друга (второй проходит первый, третий проходит второй, и т.д.) Будет ли суперкласс для всех этих классов будет First)

+0

'super.name()' существует во втором классе, хотя метод 'whoRules()' наследуется 'super.name()' в нем по-прежнему указывает на имя суперкласса 'Second', который в вашем случае это '' First "' –

ответ

3

Почему бы не быть?: ... «Вторые правила, но третий еще лучше»

Поскольку super.name() в классе Второй относится к суперклассу второго, а не суперкласс экземпляра.

От Java Language Specification: Форма super.Identifier относится к полю Идентификатор текущего объекта, но с текущим объектом, рассматриваемым как экземпляр суперкласса текущего класса.

Может ли подкласс быть суперклассом для другого класса?

Да.

Или может быть только один (суперкласс)?

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

(используя пример кода выше) Я понимаю, что первый является суперкласс для вторых, но Второй суперкласс для третьего? Или первый суперкласс для третьего?

Первый и второй являются суперклассами для Третьего.

Второй - прямой суперкласс для третьих.

+0

, когда/как это будет ссылаться на Второе? –

+0

Ключевое слово 'super' будет относиться к классу Second только в прямых подклассах Second. Если вам нужен суперкласс класса объекта, вы можете сделать это через объект класса, возвращенный из this.getClass(). –

1
Third varThird = new Third(); 

Поскольку у третьего класса нет метода whoRules(). Он вызывает метод суперкласса.

Если во время вызова объект не указан, компилятор использует это ключевое слово для вызова. Поэтому вот почему this.name() напечатал «Третий», как метод whoRules(), вызывается объектом третьего класса.Следовательно, результат - «Первые правила, но третий - еще лучше».

0

это потому, что ваш вызов супер из второго класса, который вызывает super.name() из первого класса. супер второй всегда первый

-1

Это простое наследование. Во-первых, суперкласс Second и Second - это суперкласс третьего. В основном, когда вы создаете объект класса Third, он наследует все (не частные) свойства от родительских классов, которые являются как классами First, так и Second.

First -> Second -> Third 

Супер ключевое слово - В данном примере вы переопределение (реализация метода суперкласса в subclas) имя метода() супер класса Первый в подклассе second.Using в super.name ключевое слово() позволяет вам вызвать метод name() суперкласса.

И самое главное, что я хотел бы, чтобы вы запомнили это

Java-компилятор вызывает метод, основанный на справочном типа и не тип объекта

когда вы говорите

varSecond.whoRules(); 

В этом случае ссылка на объект принадлежит к классу Во-вторых

System.out.print(super.name() + " rules");//calls the name() in class First 
System.out.println("but" + name()+"is even better");//calls the name() in class Second 

, но когда вы говорите

varThird.whoRules(); 

В этом случае ссылка на объект относится к классу третьего

System.out.print(super.name() + " rules");//calls the name() in class First 
System.out.println("but" + name()+"is even better");//calls the name() in class Third 

Просто потому, что метод имя() определяется в классе Third. Если вы не определили метод name() в классе Third, он бы назвал метод суперкласса.

и отвечая на ваш другой вопрос, нет жесткого ограничения на глубину наследования, но обычно вы не видите 10 суперклассов в иерархии в хорошем дизайне.

+0

Это неверно: «Компилятор java вызывает метод, основанный на типе Reference, а не тип объекта» –

+0

@ AndyThomas-Cramer Не могли бы вы объяснить, как это неправильно. – Shurmajee

+0

Динамический вызов метода основан на типе объекта во время выполнения, а не на ссылочном типе во время компиляции. Это один из краеугольных камней объектно-ориентированного развития. –