Kalhan.Toress
Kalhan.Toress

Reputation: 21901

why can not access child fields using parent reference

class A {
    int super_var = 1;
}

class B extends A {
    int sub_var = 2;
}

public class Demo{
    public static void main(String []args){        
        A a = new B();
        System.out.print(a.sub_var); //compile error
    }
}

why this will end with a compile error ? reference (a) referencing to an Object of B it has sub_var so why is it restricted ? why reference (a) can access only the fields in A ?

Upvotes: 2

Views: 399

Answers (6)

fastcodejava
fastcodejava

Reputation: 41097

The sub_var is in class B, so you can only access through a reference of class B. To the compiler A a = new B(); means a is an instance of class A.

Upvotes: 0

Christian Tapia
Christian Tapia

Reputation: 34146

Let's say you have these classes:

public class Animal() {
    // ...
}

public class Fish extends Animal() {
    public void swim() {...}
}

If you declared an Animal:

Animal x = new Fish();

and you called the swim() method

x.swim();

Would you expect it to work? I don't think so, because not every animal can swim. That's why you have to explicitly specify that the animal x is a Fish:

((Fish) x).swim();

In your case, if you wanted to call that method, you should specify (technically, it's called cast) the type:

System.out.print(((B)a).sub_var);

Note:

  • This works similar for methods and variables. I used a method in the example since it's more illustrative.

Edit:

Let's see this example:

Animal x;

if (some_condition)
    x = new Fish();
else
    x = new Cat();

x.swim();

This restriction exists, because Java won't know if, at execution time, the object assigned to x will have the method swim(). So to avoid this, you have to cast to the respective type to call a method that doesn't exist in superclass.

Upvotes: 6

biziclop
biziclop

Reputation: 49744

At first it does sound like it should work. (And in some languages it probably does.) But think about this example:

public class Demo {
    public static void main(String []args){        
        A a = new B();
        print( a );
    }

    public static void print( A arg ) {
        System.out.print(arg.sub_var); //compile error
    }
}

This functionally does the same thing but the print is in another method. If your version worked, this one could be expected to work too.

But what if someone then does this?

Demo.print( new A() );

This should fail because A doesn't have a sub_var. It would have to throw some kind of runtime error instead.

So the design decision in Java was not to allow this and if you declare a local variable/field/method parameter as type A, then you can only access things that every object that is either A or a subclass is guaranteed to have.

If you want to access more, you need to cast it to the subclass, which will throw an exception if you try it on an object that doesn't fit.

A a = new A(); 
System.out.print(((B)a).sub_var); //ClassCastException is thrown here 

Upvotes: 1

Stephen
Stephen

Reputation: 46

you create an object of type B and assign it to a variable of type A. The type A does not declare sub_var. This field is declared only in type B. the compiler only sees what is declared in type A, although the variable is instantiated to an object of type B.

If you want to access sub_var you would have to cast a to B.

System.out.println( ((B)a).sub_var);

Upvotes: 0

Erran Morad
Erran Morad

Reputation: 4743

Is there a variable called sub_var in the parent class ? No. That is why you get the error -

sub_var cannot be resolved or is not a field

See this

System.out.print(a.super_var); //okay
System.out.print(a.sub_var); //compile error

Upvotes: 0

RKC
RKC

Reputation: 1874

You can not access B members with the reference of Parent object A.

Instead change your println statement like below to access,

System.out.print(((B)a).sub_var);

Upvotes: 0

Related Questions