Difference between compile time and runtime reference/objects

Discussion in 'Java' started by lielar, Mar 10, 2008.

  1. lielar

    lielar Guest

    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);
    }

    }


    -----------------------------------------------------

    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'?
     
    lielar, Mar 10, 2008
    #1
    1. Advertising

  2. lielar

    Wojtek Guest

    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();

    --
    Wojtek :)
     
    Wojtek, Mar 10, 2008
    #2
    1. Advertising

  3. "lielar" <> wrote in message
    news:...
    > 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/
     
    Matt Humphrey, Mar 10, 2008
    #3
  4. lielar

    Lew Guest

    "lielar" <> wrote
    >> I have the following code
    >> -------------------------------------------------
    >> interface I {
    >> int i = 0;
    >> }


    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.

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


    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'.

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


    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 Humphrey wrote:
    > 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.

    <http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.3>:
    > 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:
    > 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 ())


    --
    Lew
     
    Lew, Mar 11, 2008
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. jakk
    Replies:
    4
    Views:
    12,282
  2. Nagaraj
    Replies:
    1
    Views:
    883
    Lionel B
    Mar 1, 2007
  3. Carter
    Replies:
    2
    Views:
    514
    Carter
    Mar 4, 2009
  4. Clinton Mead
    Replies:
    4
    Views:
    403
    James Kanze
    Dec 1, 2010
  5. Ruwan Budha
    Replies:
    4
    Views:
    1,120
    Kirk Haines
    Mar 9, 2011
Loading...

Share This Page