2013-04-03 2 views
0
class Test { 
    public static void main(String[] args) { 
     Animal a = new Dog(); 
     Dog d = new Dog(); 

     d.makeNoise(); // output "Sub" 
     a.makeNoise(); // output "Sub" then what is use of calling this. why not call d.makeNoise() only. 

    } 
} 

abstract class Animal { 
    public void makeNoise() { 
     System.out.println("Super"); 
    } 
} 

class Dog extends Animal { 
    @Override 
    public void makeNoise() { 
     System.out.println("Sub"); 
    } 
} 

У нас было 15 минут обсуждения по этой теме (15 минут слишком долго, я думаю) я объяснил интервьюеру о том, как динамический полиморфизм будет достигнуто с помощью a.makeNoise();, но все же она говорила, как дают тот же результат ,
a.makeNoise(); вывод «Sub», то, что используется для вызова этого. почему бы не вызвать d.makeNoise() только
Я тоже пошел в интерфейс, но все же вопрос заключался в том, что ссылка подкласса дает тот же результат, а затем зачем использовать ссылку на суперкласс.
динамический полиморфизм

Вопрос собеседника был, какая разница a.makeNoise(); делает? почему бы не позвонить d.makeNoise(); только тогда, когда оба дают одинаковый выход?

Какой может быть правильный ответ?

+0

возможный правильный ответ на какой вопрос? – NPE

+0

В чем вопрос? – benzonico

+0

Ответ заключается в том, что вы не понимаете полиморфизм! – John3136

ответ

2
Animal a = new Dog(); // this animal is a dog 
Dog d = new Dog();  // this dog is a dog 

Собака есть собака, однако вы объявили его.

a.getClass() всего d.getClass() всего Dog.class.

С другой стороны:

Animal a = new Animal(); // this animal is an animal 
a.makeNoise();   // prints "Super" 
+0

Я отвечаю на то же, но интервьюер ожидал чего-то еще. Что это было? – AmitG

+3

@AmitG Schweppes? – sp00m

1

Это Reason-

Animal a = new Dog(); 

Животное собака так шум будет то же самое :)

Если создать другое животное, скажем, кошка, с этим методом, и точка животное кошка, вы должны получить другой шум.

+0

Я отвечаю тем же, но интервьюер ожидал чего-то еще. – AmitG

+0

Может быть, вы должны были попробовать с интерфейсом. Следователь должен ожидать, что метод будет абстрактным в классе Animal. –

+0

Я тоже пошел на интерфейс, но все же вопрос был в том, что если ссылка на подкласс дает тот же результат, то зачем использовать ссылку суперкласса – AmitG

2

Приведенный ниже пример иллюстрирует динамический полиморфизм. Оба a и d объявляются животными, но d на самом деле является собакой.

Обратите внимание, что когда я вызываю makeNoise на Animal d, java будет знать, что d на самом деле является собакой, а не только любым животным.

class Test { 
    public static void main(String[] args) { 
     Animal a = new Animal(); 
     Animal d = new Dog(); 

     d.makeNoise(); // output "Bark" - d is an animal that barks 
     a.makeNoise(); // output "Squawk" - a is an animal that squawks 

    } 
} 

class Animal { 
    public void makeNoise() { 
     System.out.println("Squawk"); 
    } 
} 

class Dog extends Animal { 
    @Override 
    public void makeNoise() { 
     System.out.println("Bark"); 
    } 
} 
+0

Я отвечаю тем же, но интервьюер ожидал чего-то еще. Что это было? – AmitG

+1

Это не то же самое, что и ваш ответ. Посмотрите внимательно на объявление a и d. Мой пример даст отличный результат. –

+0

Я понял. Но я говорю, что я внес изменения в то, как изменил код и объяснил все это, но она ожидала чего-то еще. Я уже заметил, что вы изменили «Animal a = new Animal()», – AmitG

1

Ваш упрощенный пример не представляет случай, достаточно хорошо.

Collection<Animal> caged = getCagedAnimals(); 
for (Animal a : caged) 
    a.makeNoise(); 

Поскольку существует множество видов животных (классов), каждый из них производит другой шум. Мы не нуждаемся ни в каких приведениях, чтобы получить другое поведение, так сказать. Представьте себе ужасы, которые бы произойти, если бы мы хотим, чтобы каждое животное шуметь без полиморфизма:

for (Animal a : caged) { 
    if (a instanceof Dog) 
    ((Dog)a).woof(); // or, ((Dog)a).makeNoise() 
    else if (a instanceof Cat) 
    ((Cat)a).meow(); // or, ((Cat)a).makeNoise() 
    else {...} 
} 

Давайте есть объект типа T.Мы пытаемся вызвать ToString() (определенный класс объектов) Динамические поступления вызова метода следующим образом (на самом деле, используется виртуальная таблица метод):

C = T 
do 
    if (C defines toString()) { 
    call T.toString() 
    break 
    } 
    C = superclass of C 
while (C != null) 
throw new NoSuchMethodError(); 

Теперь, если мы имеем

Object obj = new T(); 

и мы называем

obj.toString(); 

мы на самом деле вызова ToString() класса Т.

+0

Я объяснил этот пример, но интервьюер ожидал чего-то еще. Что это было? – AmitG

0
class Account { 
    public static void main(String[] args) { 
     Animal a = new Dog(); 
     Dog d = new Dog(); 
     d.makeNoise(); 
     a.makeNoise(); 
     a = new Cat(); 
     a.makeNoise(); 
    } 
} 

abstract class Animal { 
    public void makeNoise() { 
     System.out.println("Super"); 
    } 
} 

class Dog extends Animal { 
    public void makeNoise() { 
     System.out.println("Sub"); 
    } 
} 

class Cat extends Animal { 

} 

Смотрите выше модифицированный пример и наблюдения

  1. У нас есть абстрактный класс Animal с реализацией для makeNoise (позвольте мне сказать, реализацию по умолчанию здесь)
  2. У нас есть класс Dog, который имеет тип животного но имеет индивидуальные методы makeNoise
  3. У нас есть класс Cat, который относится к типу животных, но не имеет индивидуальных методов makeNoise. он использует тип makeNoise of Animal по умолчанию.
  4. Если я использую Animal a = new Dog() и a.makeNoise(), тогда я могу удалить свой метод makenoise из класса Dog всякий раз, когда я хочу, без каких-либо изменений в какой-либо другой класс. Он будет компилироваться и выполняться без каких-либо ошибок.
  5. Если я использую Dog d = new Dog() и d.makeNoise(), то я не могу удалить метод makenoise из класса Dog, когда захочу. если я это сделаю, мне также необходимо изменить основной класс для компиляции приложения.
+0

@AmitG Я вижу, что вы отредактировали вышеупомянутый ответ, но никаких комментариев о том, было ли это полезно или нет, – Joe2013

0

Я дам один общий пример: - personA имеет один банковский счет, у него есть все разрешения на этот счет (снять, внести депозит, кредит). personB хочет внести деньги на персону. В это время он хочет получить доступ к учетной записи personA, но мы должны предоставить только разрешения на депозит.

class perosnB 
{ 
public void deposit() 
{ 
................ 
} 
} 
class personA extends personB 
{ 
public void deposit() 
{ 
...... 
} 
public void withdraw() 
{ 
...... 
} 
} 
personA p=new personB(); 
PersonB p2=new personB(); 

с помощью объекта p мы можем получить доступ только к способу вывода. используя p2, мы также можем получить доступ к депозиту. Погодный человек класс А абстрактный или нет. если personA является абстрактным классом, создающим объект для класса personA невозможно (personA p = new personA()). personA p = новый человекB() возможен.

+0

Возможно, вам понравится отредактировать ваш ответ. 'personA p = new personB();' ошибка времени компиляции. Я задумался над этим вопросом. Я также ответил на эту концепцию (только концепция с другим примером). – AmitG

0
Animal a = new Dog(); 

а является ссылкой типа животных но это относится к объекту типа собак.

Здесь Dog переопределяет makeNoise() метод животных класса.

class Animal { 
    public void makeNoise() { 
     System.out.println("Squawk"); 
    } 
} 

class Dog extends Animal { 
    @Override 
    public void makeNoise() { 
     System.out.println("Bark"); 
    } 
} 

Поскольку объект имеет Dog класса JVM будет связывать собаки класса makeNoise() метода к объекту и связывание будет сделано во время выполнения.

поэтому выход из

a.makeNoise(); 

будет

югу

1

считают, что существует 3 класса

  1. животных
  2. собака
  3. кошка кошка и собака являются подклассами животных.

class Test { 
 
    public static void main(String[] args) { 
 
     Animal a = new Animal(); 
 
     
 
    int user_input=userinput(); //returns 1 for cat and 2for dog 
 
    switch(user_input) 
 
    { 
 
    case 1:Animal d=new Cat(); 
 
    break; 
 
    case 2: Animal d=new Dog(); 
 
    break; 
 
    } 
 
     d.makeNoise(); // output "Bark"/"meow" as per user input(dynamic linking) 
 
     a.makeNoise(); // output "Squawk" - a is an animal that squawks 
 
    } 
 
    } 
 
    class Animal { 
 
    public void makeNoise() { 
 
     System.out.println("Squawk"); 
 
    } 
 
    } 
 
    class Cat extends Animal { 
 
    @Override 
 
    public void makeNoise() { 
 
     System.out.println("meow"); 
 
    } 
 
    } 
 
    class Dog extends Animal { 
 
    @Override 
 
    public void makeNoise() { 
 
     System.out.println("Bark"); 
 
    } 
 
    }

Смежные вопросы