Question

I am confused how an object is an instanceof two different classes. For example:

EnglishTest x = new EnglishQuiz();
if (x instanceof EnglishTest){
   System.out.print("P");
}
if (x instanceof EnglishQuiz){
   System.out.print("P");
} 

In both cases I get "P" printed out. My question is why?

I understand that x is of type EnglishTest but since I am doing new EnglishQuiz shouldn't that mean I am creating an instance of EnglishQuiz and not EnglishTest as well? What is going on here?

Était-ce utile?

La solution 2

class Test {
     //implicitly inherits type Object
}

class Quiz extends Test {
     //explicitly inherits type Test
     //implicitly inherits type Object
}

class PopQuiz extends Quiz {
     //explicitly inheirts type Quiz
     //implicitly inheirts type Test and Object
}

Object -> Test -> Quiz -> PopQuiz

instanceof refers to the type of the instance. If an instance implicitly or explicitly "extends" a class, it is an instanceof that type, since it inherits the type of the class its extending (and any other classes that are extended upon, as seen in my hierarchy example).

PopQuiz is both a Quiz AND a Test. Therefore, an instance of PopQuiz inherits both types Quiz amd Test, so it is an instanceof Quiz AND Test.

Autres conseils

If this line compiles:

EnglishTest x = new EnglishQuiz();

Then there must be an is-a relationship between EnglishTest and EnglishQuiz; specifically, an EnglishQuiz must be a subtype of an EnglishTest, much like how an Integer is a Number.

Thus, x instanceof EnglishTest is true, in the same way Integer instanceof Number is true. An EnglishQuiz is an EnglishTest, after all.

Looking at the Java Language Specification Section 15.20.2:

At run time, the result of the instanceof operator is true if the value of the RelationalExpression is not null and the reference could be cast (§15.16) to the ReferenceType without raising a ClassCastException. Otherwise the result is false.

Because an EnglishQuiz could always be cast to an EnglishTest (such a cast is called an upcast and is always allowed, because an object can always be classified as its supertype), the instanceof operator returns true.

Another way of visualizing this might be this:

          Object
             |
          Number
           /  \
      Integer  Float
      /     \
     Pos.  Neg.
    /  \   /  \
   1    2 -4  -5 

x instanceof y will return true if y is either the same type as x or if you can reach y by going up from x.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top