package 1

public 상위클래스{
        protected void 메소드(){
                시스템아웃프린트(10)
        }
}

---------------------------------------

package 2

public 하위클래스 extends 상위클래스{
        메인메소드{
                하위클래스 sub = new 하위클래스()
                sub.메소드();
                상위클래스 sup = sub;
                sup.메소드(); // 에러ㅋㅋㅋ
        }
}

에러나는 이유는 컴파일러의 인식때문인데 도식도로 그려봄.

생성된 객체를 sup로 참조하면 new 상위클래스(); 와 같이 생각함.
그러므로 sup로 참조하면 protected void 메소드()는 하위클래스에서 보이지 않음.
메인메소드는 하위클래스 안에 선언되서 sup로 참조가 안됨.

문제는 오버라이딩에서 나오는데... 참조변수형에 따라 객체를 다르게 인식한다는걸
쭉 이어서 다음 예제에도 적용시켜볼까함. 그리고 모순이 나오게 됨.


package 1

public 상위클래스{
        protected void 메소드(){
                시스템아웃프린트(10)
        }
}

---------------------------------------

package 2

public 하위클래스 extends 상위클래스{
        protected void 메소드(){
                시스템아웃프린트(20)
        }
}

public 메인클래스{
        메인메소드{
                하위클래스 sub = new 하위클래스()
                sub.메소드();
                상위클래스 sup = sub;
                sup.메소드();
        }
}

여기서 sub건 sup건 메소드를 호출하면 둘다 하위클래스 메소드를 호출하고
이걸 오버라이딩이라 하는데...
아까 sup로 하위클래스 객체 참조해도 상위클래스 객체 참조로 인식한다 했는데..
sup = new 상위클래스(); 이렇게 컴파일러가 인식한다면 말이야...
오버라이딩이고 머고 없는거 아니겠음?
그냥 단순히 상위클래스 객체를 받아먹는다고 인식하는건데...

이 부분이 자바 창시자 및 오라클 사람들이 기능적인 면만 강조하고 
수학처럼 모순 및 법칙에 일관되고 단순한 면이 없이 만들었단 증거겠지?
상위형으로 하위 객체를 참조하면 상위 객체로 인식하기 때문에
첫번째 예제에서 하위클래스 안에 있는 메인메소드에서 객체의 메소드를 
부를수 없었다는건데..
그렇다면 오버라이딩이라는 개념도 존재할수 없는거 아니겠음?
상위형으로 하위 객체 참조하면 상위 객체라 인식하고 그러면
상위클래스 객체 생성하는거라 가정하면 오버라이딩은 낄 자리조차 없지.
그냥 단순히 상위클래스 객체 생성하는 거닌깐..

이러면을 볼때 자바는 실용적인 면을 강조한 나머지 모순적인 면도 많은거 같음.

이게 왜 세계 최고의 프로그래밍 언어가 되었는지 궁금하다.

내 말에 잘못된 부분이 있다면 댓글을 남겨줘.