실제 작업내용인 구현부가 없는 메서드가 무슨 의미가 있을까 싶기도 하겠지만, 메서드를 작성할 때 실제 작업내용인 구현부보다 더 중요한 부분이 선언부이다.
메서드의 이름과 작업에 필요한 매개변수, 그리고 작업의 결과로 어떤 타입의 값을 반환할 것인가를 결정하는 것은 쉽지 않은 일이다. 선언부만 작성해도 메서드의 절반 이상이 완성된 것이라 해도 과언이 아니다.
... 어차피 자손 클래스에서 오버라이딩하여 자신의 클래스에 맞게 구현할 테니 추상메서드로 선언하는 것과 내용없는 빈 몸통만 만들어 놓는 것이나 별 차이가 없어 보인다. ... 하지만 abstract 를 사용해서 추상메서드로 정의해놓으면, 자손 클래스를 작성할 때 이들이 추상메서드이므로 내용을 구현해주어야 한다는 사실을 인식하고 자신의 클래스에 알맞게 구현할 것이다.
Unit[] group = new Unit[4];
group[0] = new Marine();
group[1] = new Tank();
group[2] = new Marine();
group[3] = new Dropship();
for(int i = 0; i < group.length; i++){
group[i].move(100, 200);
}
위의 코드는 공통조상인 Unit클래스 타입의 참조변수 배열을 통해서 서로 다른 종류의 인스턴스를 하나의 묶음으로 다룰 수 있다는 것을 보여주기 위한 것이다.
group[i].move(100, 200)과 같이 호출하는 것이 Unit클래스의 추상메서드인 move를 호출하는 것 같아 보이지만 실제로는 이 추상메서드가 구현된 Marine, Tank, Dropship 인스턴스의 메서드가 호출되는 것이다.
Q. 그렇다면, 클래스들의 조상 타입으로 참조변수를 선언하고, 추상 메서드를 호출하면, 인스턴스의 메서드를 호출하는 거지, 추상메서드를 호출 하는게 아닌 건가? 그런 거라면 참조 변수의 멤버가 Object여도 상관 없는 건 아닌가?
A. • 추상 메서드는 참조 변수의 타입이 아니라 실제 인스턴스의 타입에 따라 구현된 메서드가 호출됩니다.
• 참조 변수가 Object 타입이라면 Object 클래스에 정의된 메서드만 호출 가능하며, 추상 메서드 호출은 불가능합니다.
• 다형성을 활용하려면 Object 타입 대신, 추상 클래스나 인터페이스 타입을 사용하는 것이 일반적입니다.