package king.k;

public class Prince {
    public int a = 20;
    protected void kim(){
        System.out.println(a);
    }
}

================================================


package king;
import king.k.Prince;

class King extends Prince{
    
    public int a = 20;
    
    public static void main(String[] args){
        King k = new King();
        k.kim();
        Prince p = k;
        p.kim(); //에러
    }
}

상위클래스 : Prince
하위클래스 : King

코드를 더 간결하게 했습니다.

k와 p는 King 클래스의 클래스멤버 즉 현재 사용가능한 상태이자 모든 King의 공유 메소드의 지역변수입니다..
그리고 k와 p는 똑같은 객체를 바라보고 있습니다.
근데 k.kim(); 되고  p.kim();은 안됩니다.
하위클래스 King의 클래스멤버 메소드 main(String[] args)는 당연히 상속받은 모든 Prince 클래스의
public이나 protected로 선언된 멤버들을 접근 더 쉽게 말하자면 보입니다.
클래스멤버 메소드 main(String[] args)의 내부 선언된 매개변수나 지역변수들도 당연히 상속받은 모든 Prince 클래스의
public이나 protected로 선언된 멤버들을 접근 더 쉽게 말하자면 보입니다.

그런데 k.킴은 되고 p.킴은 안됩니다.

메모리 관점으로 간결하게 설명해주실 스승님 없나요.