phpclass/객체모델2005. 10. 11. 12:17
written: Oct 12 2005
추상클래스는 객체가 가지는 특성들을 추상화시켜 놓았을 뿐 아직 인스턴스화될 수 없는 클래스입니다. "상단메뉴 >> 클래스&객체 > 추상클래스"를 참조하셔서 먼저 추상클래스가 무엇인지를 이해하시기 바랍니다.
추상클래스(abstract class)
[code php;gutter:false] <?php /** * 동물(animal) 추상클래스 */ abstract class animal { abstract protected function is_body_size(); public function display($kind) { print $kind . '의 몸집은 ' . $this->is_body_size() . ".\n"; } } /** * 사자(lion) 클래스 */ class lion extends animal { protected function is_body_size() { return '크다'; } } /** * 거북이(turtle) 클래스 */ class turtle extends animal { protected function is_body_size() { return '작다'; } } $obj = new lion; $obj->display('사자'); $obj = new turtle; $obj->display('거북이'); ?> [/code]
위의 예제의 출력결과는 아래와 같습니다.
사자의 몸집은 크다.
거북이의 몸집은 작다.
lion(사자)나 turtle(거북이)라는 것이 실제로 존재하는 것이라면 animal(동물)이라는 것은 사자, 거북이 등의 특성을 가진 생물을 모두 지칭하는 추상적인 용어일 것입니다. 위의 예에서 보다시피 각 동물마다 몸집크기는 제각각일 것이고 따라서 추상클래스에서는 몸집크기를 알아내는 메쏘드 is_body_size()를 실제적으로 구현할 수 없습니다.
이와 같이 추상클래스라는 것이 실제로 객체로 생성할 수 있도록 구현된 것이 아니라 구현하고자 하는 객체들이 가지는 특성들을 추상화시켜 놓은 것입니다. 따라서 각 객체가 가지는 구체적인 특성들은 하위클래스에서 재정의(overriding)를 통해 구현해 주어야 합니다.
추상클래스라고해서 모든 멤버가 추상적이어야 하는 것은 아닙니다. 때에 따라서는 추상클래스에서도 일반클래스와 마찬가지로 실제로 구현된 멤버를 가질 수 있습니다. 동물(animal)이라는 추상적인 개념에서도 "움직인다"와 같이 실제로 구현될 수 있는 특성을 포함할 수 있는 것과 같다고 볼 수 있습니다.
[code php;gutter:false] <?php abstract class animal { abstract protected function is_body_size(); protected $action = '움직인다'; public function display($kind, $speed) { print $kind . '의 몸집은 ' . $this->is_body_size() . ".\n"; print $kind . '는 ' . $speed . ' ' . $this->action . ".\n"; } } class lion extends animal { protected function is_body_size() { return '크다'; } } class turtle extends animal { protected function is_body_size() { return '작다'; } } $obj = new lion; $obj->display('사자', '빠르게'); $obj = new turtle; $obj->display('거북이', '느리게'); ?> [/code]
위의 예제의 출력결과는 아래와 같습니다.
사자의 몸집은 크다.
사자는 빠르게 움직인다.
거북이의 몸집은 작다.
거북이는 느리게 움직인다.
위의 예에서 보시다시피 추상클래스라는 것이 그 자체로는 실제로 할 수 있는 일이 없습니다. 그러나 상속과 재정의를 통해서 매우 쓸모있는 것으로 바꿀 수 있습니다.
추상메쏘드(abstract method)
추상메쏘드는 아래의 예와 같이 함수의 몸체가 없고 단지 프로토타입만 선언해주는 메쏘드입니다.
[code php;gutter:false] abstract protected function is_body_size(); [/code]
이러한 추상메쏘드는 추상메쏘드를 포함하고 있는 클래스를 상속한 하위클래스에서 그 몸체를 실제적으로 구현해 주어야  일반 클래스처럼 객체를 생성하여 사용할 수 있습니다.
[code php;gutter:true] <?php abstract class animal { abstract protected function is_body_size(); protected static $kind = '동물'; public function display() { print self::$kind . "의 몸집은 그 종류에 따라 다릅니다.\n"; } } $obj = new animal; /* Fatal error 발생 */ $obj->display(); ?> [/code]
위와같이 추상클래스로 객체를 생성하려고 시도하면 아래와 같이 11번행에서 Fatal error가 나타납니다.
Fatal error: Cannot instantiate abstract class animal
추상메쏘드는 추상클래스 안에서만 존재할 수 있기때문에 클래스 안에 하나 이상의 추상메쏘드가 포함되어 있으면 그 클래스는 반드시 추상클래스로 지정해 주어야 합니다.
[code php;gutter:true] <?php class animal { abstract protected function is_body_size(); } /* Fatal error 발생 */ ?> [/code]
위와같이 클래스를 abstract로 지정하지 않고 추상메쏘드를 포함시키면 아래와 같이 4번행에서 Fatal error가 나타납니다.
Fatal error: Class animal contains 1 abstract methods and must therefore be declared abstract (animal::is_body_size)
추상메쏘드의 가시범위(visibility)
추상메쏘드는 하위클래스에서 반드시 구현해주어야 하기 때문에 protected 또는 public으로 지정해 주어야 하며 private로 지정할 수 없습니다.
< 추상메쏘드의 PPP 지정 및 상속 >
접근제한자 private protected public

추상메쏘드에 지정할 수 있는

접근제한자

지정할 수 없음 O O

하위클래스의 재정의된 메쏘드에서

지정할 수 있는 접근제한자

N/A

protected

public

public
 (NA:Non Applicable;해당없음).....
추상클래스의 상속
상위추상클래스를 상속받은 하위클래스에서는 상위추상클래스의 추상메쏘드를 모두 구현할 수도 있고, 새로운 추상메쏘드를 추가할 수도 있고, 상위추상클래스에 있는 일부 추상메쏘드를 구현하지 않고 계속 남겨둘 수도 있습니다. 하위클래스에 일부 추상메쏘드가 구현되지 않고 계속 남아있는 경우에 이 하위클래스도 역시 추상클래스이므로 반드시 abstract로 지정해 주어야 하며 역시 객체를 생성할 수 없습니다.
[code php;gutter:true] <?php abstract class animal { abstract protected function is_body_size(); abstract protected function is_speed(); public function display($kind) { print $kind . '의 몸집은 ' . $this->is_body_size() . ".\n"; } } class lion extends animal { protected function is_body_size() { return '크다'; } } $obj = new lion; /* Fatal error 발생 */ $obj->display('사자'); ?> [/code]
위와같이 상위추상클래스에 있는 추상메쏘드를 모두 구현하지 않은 하위클래스를 가지고 객체를 생성하려고 시도하면 아래와 같이 17번행에서 Fatal error가 나타납니다.
Fatal error: Cannot instantiate abstract class animal
위와 같은 경우에 사자(lion) 클래스를 아래와 같이 추상클래스로 수정해야 하며 상속된 하위추상클래스를 상속한 그 하위클래스에서 나머지 추상메쏘드를 모두 구현하고 난 다음에 객체를 생성할 수 있습니다.
[code php;gutter:false] <?php abstract class lion extends animal { protected function is_body_size() { return '크다'; } } class concreat_lion extends lion { protected function is_speed() { return '빠르다'; } } $obj = new concreat_lion; $obj->display('사자'); ?> [/code]

Posted by 방글24