Difference between compile time and runtime reference/objects

L

lielar

Hi

I have the following code
-------------------------------------------------
interface I {
int i = 0;
}

class A implements I {
int i = I.i + 1;

}

class B extends A {
int i = I.i + 2;

static void printAll(A obj) {
System.out.println(obj.i);
}

public static void main(String [] args) {
B b = new B();
A a = new B();
printAll(a);
printAll(b);
}

}
 
W

Wojtek

lielar wrote :
Hi

I have the following code
-------------------------------------------------
interface I {
int i = 0;
}

class A implements I {
int i = I.i + 1;

}

class B extends A {
int i = I.i + 2;

static void printAll(A obj) {
System.out.println(obj.i);
}

The signature for the printAll method specifies the 'A' class. Since
'B' extends 'A', 'B' can be passed in, however it will be treated as an
'A'.
public static void main(String [] args) {
B b = new B();
A a = new B();
printAll(a);
printAll(b);
}

}

So printAll(a) is a 'B', which is then treated as an 'A'.
printAll(b) is also treated as an 'A'
-----------------------------------------------------

I get 1, 1. As the second object I passed is of reference and object
type B , why is it that the answer it prints? Without overloading the
method, can I make it print '2'?

No. You must have:

static void printAll(B obj) {
System.out.println(obj.i);

The compiler will then choose the proper method for the class you are
passing in.

Side note: Always use properly named variables, classes. There is some
confusion with:

B b = new B();
A a = new B();
 
M

Matt Humphrey

lielar said:
Hi

I have the following code
-------------------------------------------------
interface I {
int i = 0;
}

class A implements I {
int i = I.i + 1;

}

class B extends A {
int i = I.i + 2;

static void printAll(A obj) {
System.out.println(obj.i);
}

public static void main(String [] args) {
B b = new B();
A a = new B();
printAll(a);
printAll(b);
}

}

You have 2 instance variables both called i, which is almost always a
mistake. printAll() selects the instance variable based on the compile-time
type of the expression, so it always hits the one in A.

You can make printAll print '2' for B by allowing it dispatch through
object. You don't have to overload any methods to do this.
1) add getI () { return i; } to class A
2) replace the duplicate declaration of "i" in B with i = I.i + 2 in its
constructor
3) Make printAll use the method
System.out.println (obj.getI ())

Cheers,
Matt Humphrey http://www.iviz.com/
 
L

Lew

It's bad practice to declare member variables in an interface. There's even a
name for the practice: the Constant Interface Antipattern.

The purpose of an interface is to define behavioral contracts, not implementation.

Fugly.

Consider defining instance variables as private nearly always. You need an
affirmative justification to relax the visibility even to package-private, as
you've done here.

This instance variable 'i' hides the superinterface static variable 'i'.

This instance variable 'i' hides the superclass instance variable 'i'.
static void printAll(A obj) {
System.out.println(obj.i);
}

public static void main(String [] args) {
B b = new B();
A a = new B();
printAll(a);
printAll(b);
}
}

Matt said:
You have 2 instance variables both called i, which is almost always a
mistake. printAll() selects the instance variable based on the compile-time
type of the expression, so it always hits the one in A.

The principle here is that variables do not override, only methods do.

If the class declares a field with a certain name,
then the declaration of that field is said to hide any and all accessible
declarations of fields with the same name in superclasses,
and superinterfaces of the class.

That explains the value of Matt's advice:
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,527
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top