why can not access child fields using parent reference

后端 未结 6 1806
耶瑟儿~
耶瑟儿~ 2021-01-22 06:03
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          


        
相关标签:
6条回答
  • 2021-01-22 06:12

    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);
    
    0 讨论(0)
  • 2021-01-22 06:12

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

    0 讨论(0)
  • 2021-01-22 06:21

    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
    
    0 讨论(0)
  • 2021-01-22 06:22

    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.

    0 讨论(0)
  • 2021-01-22 06:26

    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.

    0 讨论(0)
  • 2021-01-22 06:28

    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 
    
    0 讨论(0)
提交回复
热议问题