2017-02-04 7 views
0

Я хотел бы понять, как работает экземпляр.Java InstanceOf Output

Рассмотрим следующий код:

class A { } 
class B extends A { } 
class C extends B { } 
class D extends C { } 

public class TestClass{ 
    public static void main(String args[]){ 
     B b = new C(); //1 
     A a = b;  //2 
     if (a instanceof A) System.out.println("A"); //3 
     if (a instanceof B) System.out.println("B"); //4 
     if (a instanceof C) System.out.println("C"); //5 
     if (a instanceof D) System.out.println("D"); //6 
    } 
} 

Поправьте меня, если я ошибаюсь здесь, для того, чтобы InstanceOf вернуться правда, IS-A условие должно быть выполнено. Если вы посмотрите на строку // 1. Во время выполнения программа знает, что объект, обозначенный ссылкой «a», имеет тип C. Следовательно, не должно только условие на строке // 5 быть на выходе? Почему A и B также выводятся?

D не отображается, потому что объект не является экземпляром D, и поэтому здесь нет путаницы. Но я не понимаю, почему A и B отображаются в консоли.

+6

'a' является' A', потому что 'C расширяет B расширяет A'. 'a' является' B', потому что 'C расширяет B'. 'a' является' C', потому что, ну, это так. 'a' является _not_ a' D', потому что 'D extends C' и' a' является 'C'. –

+0

Спасибо за помощь. –

+0

Я поднимаю вопрос, чтобы исправить недостающие голоса. –

ответ

1

На самом деле каждая ссылка определенного класса должна ссылаться на экземпляр объекта на этот класс.

Это означает, что вы можете делать такие вещи, как B b = new C();, потому что C является подклассом B, поэтому каждый экземпляр C также экземпляр В.

думать о тех, как matrioska куклы. Каждая внутренняя кукла является суперклассом, а внешний - производным классом.

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

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

+1

Это _very_ unlear. «Инстанс С - тоже экземпляр С_» - что? «вставлять объект определенного типа, вы дублируете куклу» - что? –

+0

Первый тип, который я исправил сейчас. Вторая - аналогия, может быть, не выражена наилучшим образом, я думаю, но она должна работать. – bracco23

1

Поскольку C расширяет B и B простирается C, a является instanceofA.

Поскольку C расширяет B, a является instanceofB.

Это тривиально, что a является instanceofC.

Позвольте мне привести это в контекст. Предположим, что у вас есть три class es, Animal, CarnvorousAnimal и Lion. CarnivorousAnimal extends Animal и Lion extends CarnivorousAnimal. При создании экземпляра Lion, ваш Lion будет instanceofLion тривиальным, но это будет instanceofCarnivorousAnimal, поскольку каждый Lion также CarnivorousAnimal. Поскольку ваш объект является CarnivorousAnimal, он также будет Animal, потому что каждый CarnivorousAnimal также является Animal.

Когда вы расширяете свои классы, ваш подкласс будет более точной спецификацией. Что-то более конкретное - это пример его более общего определения, подмножества, если хотите.

1

Как упоминалось here

Объект типа подкласса также тип родительского класса.

Правило Ява

суперкласса ссылочная переменная может содержать объект подкласса.

Так ваш класс А держит ссылку на класс B и Класс B держит ссылку на класс C.

Animal        Class A 

DomesticAnimal extends Animal  Class B extends A 

Dog extends DomesticAnimal   Class C extends B 

Из приведенной выше таблицы можно сказать, Собака является для домашних животных, а такжеживотное

Животное также животных

просто класса А может быть экземпляром класса А

+0

Вы могли бы поддержать мой (более ранний, эквивалентный) ответ, поскольку я сохранил ваш. –

0

Все объекты Java являются instanceof Object.java Таким образом, любой объект при использовании instanceof ключевое слово возвращает true для Object. Это связано с тем, что все классы java получены из Object.java (все классы являются неявными подклассами или дочерними классами класса Object.java).

Ключевое слово instanceof возвращает истину

  1. объект для своего класса

  2. и для всех верхнего уровня родительских классов

  3. и для всех интерфейсов, реализуемых классом объекта и всех классов в верхней иерархии класса. Также верно возвращаются для всех высших интерфейсов уровня (интерфейсы протяженных теми, которые реализуются)

    public class GrandParent implements IGrandParent { .... }

    public class Parent implements IParent{ .... }

    public class Child implements IChild { .... }

    public interface IgrandParent extends ISpecial1,ISpecial2 { ..... }

Теперь мы видим, Child.java inherits от ISpecial1, ISpecial2, GrandParent, Parent, IParent, IGrandParent и IChild и, следовательно, instanceof для objcet Child.java будет оцениваться как true для всех вышеперечисленных классов и интерфейса, включая fir Child.java.