2016-01-12 2 views
-1
Dog d = new Dog(); // there's a toString() overridding Object's 

ArrayList container = new ArrayList(); 

container.add(d); 
container.get(0).toString; // calls toString() of Dog, however the Object is not cast to Dog 

Почему это называют Dog «s toString(), если тип времени выполнения является Object? Я знаю, что каждый объект является подклассом Object, но теперь мы работаем с суперклассом, не так ли?объекты, литье, Наследование

+0

* Почему он вызывает функцию toString(), если тип выполнения является объектом? * - Поскольку тип не является 'Object'. Вы помещаете «Собака», вы получаете «Собака». – azurefrog

+4

Думаю, вам нужно прочитать учебник по [Переопределение метода] (https://en.wikipedia.org/wiki/Method_overriding). – clcto

+0

Тип выполнения: * не * 'Объект'. Тип * объявлен * - это «Объект», но тип времени выполнения объекта всегда «Собака». – JimmyB

ответ

3

Объект - это тип времени компиляции вашей переменной. Это означает, что если вы попытаетесь запустить какой-либо метод из Dog, который не относится к Object по адресу container.get(0), вы получите ошибку компиляции.

Однако, как только вы скомпилированы, тип времени выполнения является фактическим типом экземпляра, в данном случае это Dog, поэтому вы получите toString() для Dog.

Идея состоит в том, что d является ссылкой на некоторый объект в памяти (типа Dog). когда вы скомпилируете его, ссылка имеет тип Object, поэтому вы можете позвонить только Object методам. но при запуске программы это- будет идти на реальный объект и запустить его, и это ме- один Dog

4


Нет, тип объекта не меняется, он просто остается Dog. Тот факт, что мы храним объект с ссылкой Object, не означает, что d потерял свой реальный тип.

Например:

Dog d = new Dog(); 
Object dObj = d; // object is referenced by an Object reference but is still a Dog 
dObj.toString(); // calls real method (Dog) 

Пожалуйста, подумайте об этом таким образом, как это было в реальной жизни:

  • У вас есть Dog и Cat, которые оба Animal
  • Когда ты поговорите о своих домашних животных с друзьями, которые вы ссылаетесь на ваш Dog и ваш Cat как ваш Animal s
  • Когда вы рассказываете, как ваши животные дают свой шум, они по-прежнему дают свой шум как Cat или (так что кошки мяука и лай собаки), а не как общий Animal. Они остаются теми, кто они, несмотря на то, что их ссылают на Animals.
0

Когда вы делаете

container.add(d); 

это добавить ли объект или собака? Ans: Объект Dog Тип

Аналогичным образом, когда вы делаете container.get(0), он возвращает объект типа Dog и, следовательно, вызывается метод toString.

3

При создании объекта типа Dog, то созданный объект будет иметь тип Dog, период. Методы в Java виртуальны по умолчанию, и они будут называться полиморфно.

Object obj = new Dog(); 
String s = obj.toString(); // dog's toString will be called 

Попробуйте его приведение к базовому типу,

Dog dog = new Dog(); 
Object obj = (Object)dog; 
String s = obj.toString(); // dog's toString will be called 

и ничего не изменится.

И кстати, вы используете raw type и что считается вредным

+0

Фактически, Java, в отличие от C++ или Object Pascal, имеет только * виртуальные * методы экземпляра. – JimmyB

0

Все классы являются продолжением java.lang.Object, когда вы делаете класс автоматически помещает рядом с ним extends java.lang.Object. Вы можете думать об этом как о Object или , но лично я думаю об этом как о специализированном Object, поскольку вы добавляете новые методы, переменные и код, которых раньше не было. Это также означает, что ваш класс Dog содержит все методы, перечисленные здесь: https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html

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