Здравствуйте, во время изучения таких интересных вещей как "Upcasting" и "Downcasting" объектов, столкнулся с одним довольно тревожащим меня моментом. Никак не могу понять(да и найти в течении 5-и часов тоже нигде не получилось), как именно работает даункастинг и конкретного "Почему" он так работает. Прикладываю код примера над которым я пыхтел пытаясь понять. Хотелось бы получше разобраться что происходит при a = b; И в особенности ((B)a).draw2(); Почему после a = b , для а доступны все методы класса B кроме тех, которых нету в классе А и зачем вообще ((B)a если после a = b; у нас тип уже приведён? Если несу чушь то пожалуйста остановите, весь день на этом убил и всё стало только более запутанным.
package com.company;

public class Main {

    public static class A {
       public void draw() {
            System.out.println("1");
        }
       public void draw1() {
            System.out.println("2");
        }
    }

    public static class B extends A {
        public void draw1() {
            System.out.println("3");
        }
        public void draw2() {
            System.out.println("4");
        }
    }

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


        a.draw();
        a.draw1();



        b.draw();
        b.draw1();
        b.draw2();



        a = b; //!!!!!

        a.draw();
        a.draw1();
        ((B)a).draw2(); // !!!!

    }
}