I have 3 very simple classes and a question about their inheritance.

public class A {
    int a;
    A(int a){
        this.a = a;
    }

    void meetoda(){
        System.out.println("a = " + a);
    }

    @Override
    public String toString() {
        return "A [a=" + a + "]";
    }

}




public class B extends A {
    int b;

    B(int a, int b){
        super(a);
        this.b = b;
    }

    void meetodb(){
        System.out.println("b = " + b);
    }

    @Override
    public String toString() {
        return "B [b=" + a + ", " + b + "]";
    }

}



public class TestABC {
    public static void main(String[] args) {
        A a3 = new A(45);
        B b3 = new B(34,28);
        a3 = b3;
        System.out.println(a3);
    }
}

When I print out a3, I get "B [b=34, 28]", but when I try to print a3.b, I get an error. Why?

Does class A have a b variable? a3 is defined as an instance of an A object.

No, just a.
But why does printing out a3 uses toString() method from class B?

I guess that the toString() method is overriden.

Yes, it is. Then main problem for me is that it is 50% class A (no field b, no meetodb()) & 50% class B (uses toString() from B). What is the logic behind it?

Class A with overrides.

But why does printing out a3 uses toString() method from class B?

it doesn't. but, you stated:

a3 = b3;

from that moment on, a3 actually is an instance of B, that's why it'll look for the toString method in the B class first, only if it doesn't find one there, it'll go to the parent class.

Yes,it is as if doing an implicit casting of a child type object to a parent type reference.So a3 now refers to the child type object and during runtime,due to dynamic method despatching,it uses toString of B.