2015-06-18 4 views
2

Я делаю следующее упражнение в мышления в Java 4-е издание Брюс Эккель:Приведение к базовому типу ссылки подкласс Java

Упражнение 16: (2) Создайте класс амфибий. Из этого наследуйте класс под названием Frog. Поместите соответствующие методы в базовый класс. В main() создайте лягушку и поднимите ее на амфибии и продемонстрируйте, что все методы все еще работают.

В чем разница между Frog f = new Frog(); и Amphibian f = new Frog(); в:

class Amphibian { 
    void go() { System.out.println("go"); } 
    void stop() { System.out.println("stop!"); } 
} 

class Frog extends Amphibian { 
    void go() { System.out.println("not go"); } 
} 

public class EFrog { 
    public static void main(String[] args) { 
     Frog f = new Frog(); 
     f.go(); 
    } 
} 

ответ

3

Но я не понимаю. В чем разница между Frog f = new Frog(); и амфибия f = новая лягушка();

Чтобы понять разницу, давайте добавим еще один метод в Frog, что не в Amphibian

class Frog extends Amphibian { 
    void go() { System.out.println("not go"); } 
    void come() { System.out.println("come"); } 
} 

Теперь давайте посмотрим на то, что разница:

public class EFrog { 
    public static void main(String[] args) { 
     Frog f = new Frog(); 
     f.go(); 
     f.come(); 
     Amphibian a = f; 
     a.come();//this won't compile 
    } 
} 

Нижняя линия. Frog - Amphibian, так что Frog может делать все, что угодно Amphibian может. Amphibian не является Frog, так что Amphibian не может делать все Frog может.

Когда вы говорите Amphibian a = new Frog(), вы программируете интерфейс (а не интерфейс java, но общий смысл интерфейса). Когда вы говорите Frog f = new Frog(), вы программируете реализацию.

Сейчас подходит к актуальному вопросу о том, что книга просит вас попробовать:

В основных(), создайте Frog и базовый тип его Амфибию и продемонстрировать , что все методы по-прежнему работать.

public class EFrog { 
     public static void main(String[] args) { 
      Frog f = new Frog(); 
      Amphibian g = (Amphibian)f;//this is an upcast 
      g.go(); //okay since Amphibian can go 
      g.come();//not okay since Amphibian can't come     
     } 
    } 

Я не думаю, что вы хотели спросить Что толку но приведение к базовому типу, так как название уже отредактирован кем-то еще, то почему бы не ответить на этот вопрос, а? Ускорение полезно в определенных ситуациях, таких как вызов специализированных форм перегруженных методов явно. См. this ответ за дополнительную информацию.

1

В этой простой программе, не существует на самом деле никакой разницы. Но если у вас есть Amphibian f, он может обратиться к любой земноводной, а не только к Frog. Вы все еще используете все методы, которые предоставляет Amphibian, даже если это экземпляр Frog См. What is polymorphism, what is it for, and how is it used? для описания полиморфизма.

0

Это то, что мы знаем как полиморфизм. Это много форм. Многие формы одного и того же объекта. Тот же объект можно назвать Лягушкой, и его можно назвать амфибией, как вы узнали. Когда реферал является амфибией, все же исходным объектом является Frog, поэтому вызывается метод overridden.

0

Too увидеть разницу, вы можете добавить метод прыжок() к Frog (но не до базового класса Амфибия:

class Amphibian { 
    void go() { System.out.println("go"); } 
    void stop() { System.out.println("stop!"); } 
} 

class Frog extends Amphibian { 
    void go() { System.out.println("not go"); } 
    void jump() { System.out.println("jump!"); } 
} 

public class EFrog { 
    public static void main(String[] args) { 
     Frog f = new Frog(); 
     f.go(); 
     f.jump(); // works 
     Amphibian a = new Frog(); 
     a.jump(); // will not compile! 
    } 
} 
0

Это один простой Если вы используете как ниже

Frog f = new Frog();

Тогда вы не можете бросить его на любой другой тип. Однако вы можете назвать все Frog методы.

Но если вы используете, как показано ниже

Amphibian f = new Frog();

вы можете изменить объект некоторых других земноводных, не изменяя его ссылки просто делать, как это.

f = new SomeOtherAmphibian();

Этот способ кодирования является очень популярным и известен как кодирования базового класса или интерфейса

1

В чем разница между Frog f = new Frog(); и Amphibian f = new Frog();

от вашего Например, мы можем видеть, что Frog наследует Amphibian. Таким образом, любая переменная, объявленная типа Amphibian, всегда может хранить экземпляр объектов, которые имеют суперкласс как Amphibian в вашем случае Frog. Что касается кода примера, то это не имеет никакого значения.

Но есть тонкая разница между двумя, которые не могут быть найдены в вашем примере. Рассмотрим следующий пример:

class Frog extends Amphibian { 
    void go() { System.out.println("not go"); } 
    void croak(){ System.out.println("croak");} //Added this extra line 
} 

Теперь, если вы храните ваш Frog экземпляр в качестве

Amphibian f = new Frog(); 
f.croak(); //This will not work. 

Это не работает, как, потому что JVM рассматривает е как тип Amphibian и в Amphibian классе нет метода croak. Поэтому возникает ошибка. Но если вы храните это нравится:

Frog f = new Frog(); 
f.croak(); //This will work. 

Это работает, потому что JVM рассматривает е как тип Frog и класс Frog имеет метод croak.

Конечно, вы можете сделать предыдущий случай работы по типу отливки п к Frog как:

Amphibian f = new Frog(); 
((Frog)f).croak(); //This will work. 
Смежные вопросы