In the example below (from my coursepack), we want to give to the Square instance c1 the reference of some other object p1, but only if those 2 are of compatible types.
if (p1 instanceof Square) {c1 = (Square) p1;}
What I don't understand here is that we first check that p1 is indeed a Square, and then we still cast it. If it's a Square, why cast?
I suspect the answer lies in the distinction between apparent and actual types, but I'm confused nonetheless...
Edit:
How would the compiler deal with:
if (p1 instanceof Square) {c1 = p1;}
Edit2:
Is the issue that instanceof checks for the actual type rather than the apparent type? And then that the cast changes the apparent type?
Old code will not work correctly
The implied cast feature is justified after all but we have trouble to implement this FR to java because of backward-compatibility.
See this:
public class A {
public static void draw(Square s){...} // with implied cast
public static void draw(Object o){...} // without implied cast
public static void main(String[] args) {
final Object foo = new Square();
if (foo instanceof Square) {
draw(foo);
}
}
}
The current JDK would compile the usage of the second declared method.
If we implement this FR in java, it would compile to use the first method!
🔴 JDK 14
We finally implemented this feature in JDK 14. As you might have noticed you can declare a new variable within the instanceof-linkage. This new variable has been defined by the value of a automatically downcast to the specified type.
if (any instanceof String s) {
System.out.println(s);
}
Keep in mind, you could always assign an instance of Square to a type higher up the inheritance chain. You may then want to cast the less specific type to the more specific type, in which case you need to be sure that your cast is valid:
Object p1 = new Square();
Square c1;
if(p1 instanceof Square)
c1 = (Square) p1;
The compiler does not infer that since you are in the block, you have done a successful check for the type of the object. An explicit cast is still required to tell the compiler that you wish to reference the object as a different type.
if (p1 instanceof Square) {
// if we are in here, we (programmer) know it's an instance of Square
// Here, we explicitly tell the compiler that p1 is a Square
c1 = (Square) p1;
}
In C# you can do the check and the cast in 1 call:
c1 = p1 as Square;
This will cast p1 to a Square, and if the cast fails, c1 will be set to null.
Just to provide an update on this, Java 14 now provides pattern matching for instanceof, this allows you to check and cast in one fell swoop.
This (old way):
void outputValue(Object obj) {
if (obj instanceof String) { // Compare
String aString = (String) obj; // New variable & explicit casting
System.out.println(aString.toUpperCase()); // Access member
}
}
Can be simplified to this:
void outputValue(Object obj) {
if (obj instanceof String aString) { // Compare and cast (if true)
System.out.println(aString.toUpperCase()); // Access member
}
}
There's a difference between measuring if some object will fit in a box, and actually putting it in the box. instanceof is the former, and casting is the latter.
Because this particular syntactic sugar is not yet added to the language. I think it was proposed for Java 7, but it doesn't seem to have entered project coin
E.g. If you hand over p1 as of type Object, the compiler wouldn't know that it is in fact an instance of Square, so that Methods etc. wouldn't be accessible. The if simply checks for a certain type to return true/false, but that doesn't change the type of the variable p1.
The test is done to prevent from ClassCastExceptions at runtime:
Square c1 = null;
if (p1 instanceof Square) {
c1 = (Square) p1;
} else {
// we have a p1 that is not a subclass of Square
}
If you're absolutly positive that p1 is a Square, then you don't have to test. But leave this to private methods...
The variable p1 has whatever type it started with - let's say Shape. p1 is a Shape, and only a Shape, no matter that its current contents happen to be a Square. You can call - let's say - side() on a Square, but not on a Shape. So long as you are identifying the entity in question via the variable p1, whose type is Shape, you can't call side() on it, because of the type of the variable. The way Java's type system works, if you can call p1.side() when you happen to know it's a Square, you can always call p1.side(). But p1 can hold not just Square Shapes, but also (say) Circle Shapes, and it would be an error to call p1.side() when p1 held a Circle. So you need another variable to represent the Shape which you happen to know is a Square, a variable whose type is Square. That's why the cast is necessary.
Not to be obnoxious, but you have to tell the compiler what you want to do because the alternative would be for it to guess what you're trying to do. Sure, you might think, "If I'm checking the type of an object, OBVIOUSLY that must mean that I want to cast it to that type." But who says? Maybe that's what you're up to and maybe it isn't.
Sure, in a simple case like
if (x instanceof Integer)
{
Integer ix=(Integer) x;
...
My intent is pretty obvious. Or is it? Maybe what I really want is:
if (x instanceof Integer || x instanceof Double)
{
Number n=(Number) x;
... work with n ...
Or what if I wrote:
if (x instanceof Integer || x instanceof String)
What would you expect the compiler to do next? What type should it assume for x?
RE the comments that instanceof is obsolete or otherwise a bad idea: It can certainly be mis-used. I recently worked on a program where the original author created six classes that all turned out to be pages and pages long, but identical to each other, and the only apparent reason for having them was so he could say "x instanceof classA" versus "x instanceof classB", etc. That is, he used the class as a type flag. It would have been better to just have one class and add an enum for the various types. But there are also plenty of very good uses. Perhaps the most obvious is something like:
public MyClass
{
int foo;
String bar;
public boolean equals(Object othat)
{
if (!(othat instanceof MyClass))
return false;
MyClass that=(MyClass) othat;
return this.foo==that.foo && this.bar.equals(that.bar);
}
... etc ...
}
How would you do that without using instanceof? You could make the parameter be of type MyClass instead of Object. But then there's be no way to even call it with a generic Object, which could be highly desirable in many cases. Indeed, maybe I want a collection to include, say, both Strings and Integers, and I want comparisons of unlike types to simply return false.
As Leroy mentioned, Java 14 introduces pattern matching for instanceof. So, you can combine both instanceof check and typecast altogether in a single expression:
if (p1 instanceof Square) {
c1 = (Square) p1;
}
can be rewritten as
if (p1 instanceof Square c1) {
// use c1
}
This feature is finalized in Java 16 (JEP 394). For the below versions, refer this link to enable this preview feature from IDEs such as IntelliJ, Eclipse, and STS.
If c1 is declared as a type of Square then casting is required. If it is a declared as an Object then casting is not needed.
Related
Sorry if the title is poorly worded, I don't really know how to ask this. But I want to distinguish between instances of the same class, but referenced as different classes. Please consider following code:
class Shape {}
class Circle extends Shape {}
class Main {
public static void main(String[] args) {
Circle myCircle = new Circle();
Shape myOtherCircle = new Circle();
System.out.print(myCircle.getClass() + ", ");
System.out.println(myOtherCircle.getClass());
System.out.print((myCircle instanceof Circle) + ", ");
System.out.println(myOtherCircle instanceof Circle);
System.out.print((myCircle instanceof Shape) + ", ");
System.out.println(myOtherCircle instanceof Shape);
System.out.print(Circle.class.isInstance(myCircle) + ", ");
System.out.println(Circle.class.isInstance(myOtherCircle));
System.out.print(Shape.class.isInstance(myCircle) + ", ");
System.out.println(Shape.class.isInstance(myOtherCircle));
}
}
We can distinguish objects by the type of their instance by using the methods or operators shown above, but as shown, when trying to compare objects by the type of the reference there are no differences the code prints this:
class Circle, class Circle
true, true
true, true
true, true
true, true
How can I distinguish myCircle and myOtherCircle by the type reference. Thank you for reading, I appreciate all answers.
I don't think that is possible. The closest you can get is if these variables are fields of a class. Then you can access the type via the class definition:
class Main {
Circle myMainCircle = new Circle();
Shape myMainOtherCircle = new Circle();
static class Shape {
}
static class Circle extends Shape {
}
public static void main(String[] args) throws Exception {
System.out.println(Main.class.getDeclaredField("myMainCircle").getGenericType());
System.out.println(Main.class.getDeclaredField("myMainOtherCircle").getGenericType());
}
}
output:
class Main$Circle
class Main$Shape
The problem I see is "When would you not know the reference type?" For example we could make two methods.
public int special(Circle a){
return 1;
}
public int special(Shape a){
return 2;
}
Then using your example.
System.out.println(special(myCircle) + ", " + special(myOtherCircle));
(This will print 1,2 because java will use the most specified method. myCircle is a Circle and a Shape, but the Circle is the most specified.)
For this to work though, we already know that one class is referenced as a Shape and the other a Circle.
In other words, you want to know, at runtime, the declared type of a reference to a variable (and not a class field - since you can use introspection to check out those, as shown by Conffusion's answer)
Why would you need to check it at runtime? In what case could it be useful to wait until then? The compiler knows much earlier -- at compile time, as it keeps track of the declared types of all identifiers. In your code, if you write
Shape myOtherCircle = new Circle();
// ...
Circle c = myOtherCircle; // compile-time error: invalid implicit cast
This warns you, at compile-time, that you are doing something fishy - as the compiler does not allow implicit (= non-explicit, that is, without an expliccit (Circle) cast) narrowing casts. For example: implicit casting from a Shape to a Circle: bad, because you could try to convert a Square-Shape to a Circle which would lead to run-time errors. From a Circle to a Shape, a broadening cast, no errors can occur.
So, my short answer would be:
you cannot do this at run-time because the compiler (and your IDE) already has this information at compile-time
On the other hand, with computers, almost everything is possible, although some are quite complicated. It is possible to detect such problems at runtime by using the JDK's built-in java compiler to (uh) compile and report on the declared types of variables in any piece of java code - but doing so is certainly not expected (most folks using it just want to compile and run code at runtime, rather than play with the AST), and requires a deep dive into internals. Asides from the JDK's own compiler, you can also use any of a large set of java compilers to do something similar (but beware possible incompatibilities with the standard one).
In Java, a Circle instance is a Circle, no matter if you store a reference to it in a variable declared as e.g. Circle, Shape or Object.
So, anything you do with the instance found in a variable only depends on the instance's class, not on the variable's declared type. That applies to things like the instanceof operator, the getClass() method and so on.
There's one exception: if you have some overloaded methods like
String myType(Object x) { return "Object"; }
String myType(Shape x) { return "Shape"; }
String myType(Circle x) { return "Circle"; }
then the compiler will decide which version to call, based on the type as it is known at compile-time. And if you pass a variable into a call of myType(), the type that the compiler assumes will be the variable's type, not knowing about the class of the instance that will later be referenced in the variable.
So then the following snippet might do what you want:
System.out.print(myType(myCircle) + ", ");
System.out.println(myType(myOtherCircle));
But, as for any given variable you statically know how you declared it, I don't see how such a construct might be useful.
Consider this code:
public interface I { I f(I x); }
public class C1 implements I { public I f (I x) { return null; } }
public class C2 implements I { public C2 f (I x) { return null; } }
public class C3 implements I { public I f (C3 x) { return null; } }
public class C4 implements I { public C4 f (C4 x) { return null; } }
public class C5 implements I { public C1 f (I x) { return null; } }
If you try to compile, you will see that C3 and C4 fail:
C3 is not abstract and does not override abstract method f(I) in I
C4 is not abstract and does not override abstract method f(I) in I
So I am allowed to specialize the return type, but the argument must remain abstract. In other
words, I am allowed to specify the return type of the method (it may even be C2 in the definition
of C1 — I can mix), but I cannot restrict the arguments, so f is always polymorphic on the
input.
What is the logic behind this situation?
Why is it not allowed to specialize the argument?
Why is it allowed to specialize the return type to the type of this or keep it abstract?
Why is it allowed to specialize the return type to another implementation of the same interface?
(Like in C5.)
P.S. That other question about covariant return obviously does not cover all the points above, if any.
I am not asking "what", I am here asking "why".
Yet again, my question here is about relation of a class to an interface, not subclassing in general (even if we do consider implementing an interface a case of subclassing, which is an open, though philosophical, question in itself).
And yet once more, that question is general, while my question is specific to Java.
Finally, the wording is completely different. I do not even know where this "covariant" comes from. Like in "vector" covariant? "Functor" covariant? If there is deep analogy, it has got to be explained.
So please kindly reopen.
Let's see.
public interface I { I f(I x); }
I[] all = { new C1(), new C2(), new C3(), new C4(), new C5() };
I argument = availableArguments[Random.nextInt(all.length)];
I c1 = new C1();
I c2 = new C2();
I c3 = new C3();
I c4 = new C4();
I c5 = new C5();
public class C1 implements I { public I f (I x) { return null; } }
I result = c1.f(argument); // ok; argument is an I, an I is returned
public class C2 implements I { public C2 f (I x) { return null; } }
I result = c2.f(argument); // ok; argument is an I, returned C2 can be assigned to I
public class C3 implements I { public I f (C3 x) { return null; } }
I result = c3.f(argument); // would fail: argument is not of type C3 as required
public class C4 implements I { public C4 f (C4 x) { return null; } }
I result = c4.f(argument); // would fail: argument is not of type C4 as required
public class C5 implements I { public C1 f (I x) { return null; } }
I result = c5.f(argument); // ok; argument is an I, returned C1 can be assigned to I
The story goes some way here.
Interfaces are a kind of classes.
It is not immediately obvious, but another fitting name for an "interface" of Java would be an "abstract class". That interfaces are in fact a subset of classes is of course questionable, so we should question it separately. If we find out that it is false, we should revisit this answer as well. But for now, let us assume that it is true.
We also have to assume that Java "classes" are a kind of types. This can, again, be questioned in itself, elsewhere. If we assume this, we can draw some insight from the theory of types. What we need specifically is the notion of subtyping. In short, that C is a subtype of I means that when you have a variable of type I in your code, you can replace it with that of type C and some part of your code will still work.
Side notes:
Of course, you can never actually create a value of type I, since I is an abstract class — it has no definition; but you may consider a value of which it is known only that it is of some class that implements I.
Which part of your code will work afterwards depends on the exact definition of subtyping, of which there are some — read on to find out which definition Java is using.
Argument and return types are fundamentally distinct with respect to subtyping.
This is where covariance and contravariance enter. These terms have come to computer science from physics and through category theory. That seems far fetched, but take a look at how subtyping plays with functions and you are sure to see how it all aligns.
Here is an example. It is a bit involved, so take a pen, some paper and check it for yourself.
Take a function f: Integer -> Boolean. It takes a number and returns a truth value. For instance, let it tell us whether the number is even.
We can subtype this function in the following 2 ways:
Surely, if it works on any number, it will work on primes, so we can use the same function like this: f -- specialize argument --> f1: Prime -> Boolean. (3 still gives False, 2 gives True. All is good.) Where the latter works, the former would work too. So, f1 is a subclass of f.
It is also true that we can use the same function like this: f -- generalize result --> f2 = Integer -> Byte. (We would simply convert True to 0x01 and False to 0x00.) Where f2 is needed, f will do. So, f2 is a subclass of f too!
See that Prime is a subclass of Integer: you can still add, multiply and invert them, but you can also use them for cryptography.
See that Bool is a subclass of Byte: you can still store it in memory, but you can also store an array of Bool packed, in 8 times smaller memory than an array of Byte.
Now observe: when we move the argument of f in the direction of subtyping (specialize it), the function also moves in that direction, while the result type has to be moved in the opposite direction (get generalized) for a function to be subtyped. The reader may actually draw this and see how it aligns with the definition of vector variance in physics.
This is of course not a real proof, just some hand waving. I have no real proof. Do question!
Subclassing in Java aligns with a certain "subtyping" partial order on types.
The famous Barbara Liskov's subtype requirement is one way to define the subtyping relation. That particular definition is called "behavioural" subtyping, and it opens a deep rabbit hole of undecidability which may or may not be of a concern for us. (So again we have a question.) It is here we have to take it on faith that Java is faithful in its rendition of behavioural subtyping. (Habitually question it. One possible way to drive a wedge is look attentively at the relationship between subtyping and inheritance.)
So let us suppose that inheritance is compatible with subtyping in Java. What does it give us?
A function with subtyped argument is not a subtype of the original.
That is, a method of a subtyped item is not a subtype of the original.
So suppose you have this function that performs RSA encryption and it just needs one prime, f: Prime -> X. If you put this function in situation where a non-prime argument can be given to it, then it will likely create a message that is encrypted very weakly. You introduced a bug. So, while you can always put a prime to a place where a number is expected, you cannot put a method invocation that requres a prime to a place where a mere number will be given to it as an argument.
But the object the method is invoked from is itself an implicit argument, you may ask, so subclassing should be forbidden altogether! Indeed, suppose I define a method of Integer that computes a possibly weak RSA key and subclass Prime from this Integer. Now the same method, with the same evident types, computes a strong RSA key, because its implicit argument has been subtyped — and, if I want strong keys, I cannot blindly replace Integer with Prime.
This is the first big question of our fantasy adventure.
(I am very fuzzy at this point.)
Java tries to make sure an implementation of a method is always a subtype of its definition.
One way of ensuring that is to only allow subtyping the result. (Is it the only way? Right way? Is it actually safe?)
For some reason, Java does not try to give type errors at use site, but simply forbids the definition.
What is the reason for that is our big question number two. Possibly because it wants to align subtyping and inheritance.
So, I use IntelliJ IDEA to program in Java, and I was experimenting with the keyword instanceof and my code looked eventually like this:
public class Main {
public static void main(String args[])
{
One one = new One();
One two = new Two();
if (one instanceof Two)
{
System.out.println(one);
}
if (two instanceof Two)
{
System.out.println(one);
}
}
}
class One { }
class Two extends One { }
IntelliJ gives me at the two instanceof Two line a hint "[...] is allways true", but for one instanceof Two IntelliJ doesn't give me a "[...] is always false" hint. Does anyone know why?
Updated: fixed in IDEA 2018.3.
(Disclaimer: IntelliJ IDEA developer is here, who is responsible for this feature).
Short answer: because it's not implemented.
When we track an actual type of variable within the data flow analysis, we use a model described by TypeConstraint class. It allows us to track the facts of two kinds: 1) if variable actual type is instanceof something and 2) if variable actual type is not instanceof something. Having these facts we can infer always true/always false instanceof in many cases E.g.:
void test(Object foo) {
if (foo instanceof String) {
if (foo instanceof Integer) {
// always false: "instanceof String" fact is not compatible
// with "instanceof Integer"
}
}
}
Or
void test(Object foo) {
if (!(foo instanceof Number)) {
if (foo instanceof Integer) {
// always false: "not instanceof Number" fact is not compatible
// with "instanceof Integer"
}
}
}
However for your case this model is not enough. We need to extend it to track the exact type of variable. In your code we track that one is instanceof One (which is compatible with instanceof Two fact), despite from the new expression we could know more precise type information that one is exactly One. This is not often usable, because in most of the cases (variable is method parameter, variable is returned from method, variable is assigned from field, array element, cast expression etc.) we cannot know whether the type is exact or subtype, so the current model is completely satisfactory. I can imagine only two cases where exactly One fact tracking is useful: the new expression (like in your case) and after comparison like obj.getClass() == Xyz.class.
I think, it's a reasonable feature to implement. I already thought about this, but as somebody else besides me also cares, I filed an issue, so you can track it.
I'm studying 'instanceof' java, but I couldn't understand 'instanceof' clearly, I thought below answer would be true and false, but result is both true. Could you explain why this result happen? As I know, when A is child of B (Parent), and a instanceof B is 'false' but result is different with what I thought.
class Car{
String color;
int door;
}
class FireEngine extends Car{
void water(){
System.out.println("water");
}
}
public class Operator {
public static void main(String[] args) {
Car car = new FireEngine();
FireEngine fireCar = new FireEngine();
System.out.println(car instanceof FireEngine);
System.out.println(fireCar instanceof Car);
}
}
Declaration != Value
You declare car as an Car, but the Value is an FireEngine.
instanceof works based on values, not on the declarations of their variables!!!
Shortening may help to understand:
System.out.println(new FireEngine() instanceof FireEngine); // true
System.out.println(new FireEngine() instanceof Car); // true
The output of instanceof depends on the runtime type of the variable whose type you are testing. The compile time type of the variable doesn't matter (as long as it is possible that x instanceof Y will return true for some value of x, otherwise the expression won't pass compilation).
Both car and fireCar hold instances of FireEngine in your code. And since FireEngine is a kind of a Car, both car and fireCar are instanceof both Car and FireEngine, so your code prints true and true.
Implementation of the Instanceof operator. Returns a Boolean if the Object parameter (which can be an expression) is an instance of a class type.
Input 1: An object or Expression returning an object.
Input 2: A Class or an Expression returning a Class
Returns: A Boolean that is the result of testing the object against the Class.
For more information please go throught the javadocs # http://docs.oracle.com/cd/E13155_01/wlp/docs103/javadoc/com/bea/p13n/expression/operator/Instanceof.html
For more detailed explanation with examples please go through the following web page : http://mindprod.com/jgloss/instanceof.html
In Java there are two types of bindings: static (the reference type)
and dynamic (the object type).
In your case:
Car car = new FireEngine();
Car is the static type and FireEngine is dynamic type. It means, you are actually working with a FireEngine (the object type). You can imagine Car as a special pointer with a car shape pointing to the real object that is your awesome FireEngine. If you read 'instanceof' you can understand it, this method tell you if an object is an instance of a class, not the reference. So the compiler will see: FireEngine (car) instanceOf FireEngine? Of course, let's return a true!
You can have a look to this post also: What is the 'instanceof' operator used for?
The statement
As I know, when A is child of B (Parent),
and a instanceof B is 'false' but result is different with what I thought.
is not correct. instanceof does not check for the child, it tests for the parent.
I have two classes and an interface shown below.
Quick summary: Interface Winterface, Class Big, Class Little that extends Big and implements Winterface.
public interface Winterface {}
public class Big {
public int hello = 88;
public Big() {}
public void theMethod() {
System.out.println ("Big was here: " + (this instanceof Winterface) + ", " + this.hello);
}
}
public class Little extends Big implements Winterface{
private boolean hello = true;
public Little(){}
public void theMethod() {
super.theMethod();
System.out.println("Little was here: " + hello);
}
public static void main(String [] args) {
Little l = new Little();
l.theMethod();
}
}
When I execute the main in Little, I get the following output
Big was here: true, 88
Little was here: true
my question is, how can
1) (this instanceof Winterface) return true but
2) this.hello be 88?
If this.hello = 88, then this = Big, which isn't an instance of Winterface.
I do not understand how this is possible, thanks in advance
EDIT: THANKS everyone I understand now that 'this' refers to little, which is a Big and implements Winterface. Since the method is being called as super.theMethod(), the variable 'hello' available is the one in Big even though 'this' refers to little.
this can only be one class. However this.hello is the field accessible to that class.
As this can only be one class it is a Little which has a parent Big and implements Winterface When you call a method in its parent which can only see hello that is what it sees.
i.e. Java supports polymorphism for methods but not fields.
l is Little but Little is a Big and also implements the behavior of Winterface.
The super is a call to the parent class so the hello member of the parent class (i.e. Big) is used.
You are not doing this.hello but super.theMethod() that uses the parent's class member variable hello.
UPDATE:
The super.theMethod() invokes the corresponding method in the parent class. In the parent class you access the fields of the parent (which also belong to the derived class since Little is also a Big). So the this.hello at that point is accessing the part of the code that is of the parent class.
You can imagine the memory print of Little as follows:
++++++++
+ Big +
--------
+Little+
++++++++
So Little has all the members variables of the parent i.e. Big and when the code runs inside super.theMethod() it is running inside the "code area" of Big.
As Peter states in his answer, polymorhism is not supported for methods and I hope that this overly simplistic description helps understand this
This is because the this instanceof ... check does not use the static (i.e., compile-time) type (which is Big), but the object's (this') dynamic run-time type (i.e., this.getClass()), which is Little in your example. If it would use the static type, the operator would be pretty pointless, since we would have:
Object obj = "foo";
if (obj instanceof Object) { /* always entered */ }
/* but */ if (obj instanceof String) { /* never entered */ }
statically, at compile-time. The purpose of the instanceof operator is to enable run-time type testing, for example:
Object obj = /* whatever */;
if (obj instanceof String) {
String str = (String)obj; // Cast cannot fail
...
} else if (obj instanceof Long) {
Long val = (Long)obj; // Cast cannot fail
...
}
Note, that this technique should only be used sparingly.
Your variable is an instance of Big and of Little. It's a direct instance of Little, but since Little inherits from Big the instanceof operator will return true for Big too.
Little l = new Little();
System.out.println(l instanceof Little); // true, l is an instance Little
System.out.println(l instanceof Big); // true, l is an instance of Little which inherits from Big
Your other misunderstanding (I'm assuming) is how the 'method lookup' works. When you call theMethod the it picks Little's implementation of that method. When you call super.theMethod though, you've explicitly said "call Big's version of this method", and then inside that method it's using Big's hello variable rather than Little's hello variable.
What is happening here is that when you are defining your variable hello in Little you are not overwriting the variable hello that is inside Big you are defining a new variable hello within Little that is hiding the variable hello within Big. Thus within the scope of Big, hello will refer to the integer value of 88 and within the scope of Little, hello will refer to true. These are different variables both contained within your object, the only difference is the scope by which you refer to them.
Like others here have said, instanceof is an operator that compares the runtime type of your object (what is returned by this.getClass()). When in Big even though the scope of the variables within your object will refer to Big, this is still of runtime type Little which is why it is an instance of Winterface.