PHP - 추상 클래스

PHP 프로그래밍의 세계로 여러분을 초대합니다! 오늘 우리는 PHP의 가장 강력한 기능 중 하나인 추상 클래스에 대해 깊이 있게 탐구해보겠습니다. 시작하기 전에, 저의 추상 클래스에 대한 첫 경험을 나누고 싶습니다.

PHP - Abstract Classes

어느 날, 작은 마을 '코드빌'에 살고 있던 젊은 프로그래머 아이리스는 게임을 만들고 싶었습니다. 그녀는 텍스트 기반 어드벤처 게임을 만들어보는 훌륭한 아이디어를 가지고 있었지만, 먼저 몇 가지 기본 구조를 짜야 했습니다. 그때 그녀는 추상 클래스를 발견했습니다.

아이리스는 추상 클래스가 그녀의 게임에서 모든 캐릭터들이 공유할 수 있는 공통된 동작과 속성을 정의할 수 있게 해주어서 기뻐했습니다. 그녀는 이러한 추상 클래스를 상속받아 특정 캐릭터 클래스를 만들 수 있었고, 각 캐릭터가 필요한 속성과 메서드를 새로 작성하지 않고도 가지게 할 수 있었습니다.

이제 튜토리얼로 돌아가겠습니다. PHP에서 추상 클래스는 인스턴스화할 수 없고 다른 클래스에 의해 상속되도록 고안된 클래스입니다. 추상 클래스는 추상 메서드(구현이 없이 선언된 메서드)와 구체 메서드(구현이 있는 메서드)를 모두 포함할 수 있습니다.

예제

추상 클래스의 개념을 이해하기 위해 간단한 예제를 시작해보겠습니다. 우리는 Animal이라는 추상 클래스를 만들고, 그것을 상속하여 두 개의 특정 동물 클래스 DogCat을 만듭니다.

abstract class Animal {
protected $name;

public function __construct($name) {
$this->name = $name;
}

abstract public function makeSound();

public function getName() {
return $this->name;
}
}

class Dog extends Animal {
public function makeSound() {
return "Woof!";
}
}

class Cat extends Animal {
public function makeSound() {
return "Meow!";
}
}

$dog = new Dog("Buddy");
echo $dog->getName() . " says: " . $dog->makeSound() . "\n"; // 출력: Buddy says: Woof!

$cat = new Cat("Whiskers");
echo $cat->getName() . " says: " . $cat->makeSound() . "\n"; // 출력: Whiskers says: Meow!

이 예제에서 우리는 Animal 추상 클래스에 생성자와 makeSound() 메서드가 있습니다. makeSound() 메서드는 상속받는 클래스에 의해 구현되어야 합니다. getName() 메서드는 구체 메서드로, 구현이 있어서 클래스 인스턴스에 의해 직접 사용될 수 있습니다.

DogCat 클래스는 Animal 클래스를 상속하고 makeSound() 메서드의 자신만의 구현을 제공합니다. DogCat의 인스턴스를 만들 때, makeSound() 메서드를 호출하면 각 동물에 맞는 소리를 출력합니다.

PHP에서 인터페이스와 추상 클래스의 차이

이제 추상 클래스의 작동 방식을 보았으니, 잠시 인터페이스와 비교해보겠습니다. 인터페이스와 추상 클래스는 모두 클래스에 대한 계약을 정의하는 데 사용되지만, 몇 가지 중요한 차이가 있습니다:

  1. 구현: 인터페이스는 추상 메서드만 포함할 수 있지만, 추상 클래스는 추상 메서드와 구체 메서드를 모두 포함할 수 있습니다. 만약 클래스 계층에서 기본 동작을 제공해야 한다면 추상 클래스를 사용해야 하고, 기본 동작이 없는 계약만 정의하고 싶다면 인터페이스를 사용해야 합니다.

  2. 다중 상속: 클래스는 여러 개의 인터페이스를 구현할 수 있지만, 하나의 추상 클래스만 상속할 수 있습니다. 이는 PHP가 클래스의 다중 상속을 지원하지 않기 때문입니다. 이는 공통 상태와 메서드 결정을 관리하는 데 어려움을 줄 수 있습니다.

  3. 속성: 인터페이스는 속성을 포함할 수 없지만, 추상 클래스는 포함할 수 있습니다. 만약 여러 클래스 간에 공통된 속성을 정의하고 싶다면 추상 클래스를 사용해야 합니다.

  4. 메서드 가시성: 인터페이스의 모든 메서드는 묵시적으로 공개됩니다. 반면에 추상 클래스에서는 메서드의 다양한 가시성 수준(공개, 보호, 사적으로)을 정의할 수 있습니다.

  5. 생성자: 인터페이스는 생성자를 포함할 수 없습니다. 인터페이스는 행동을 정의하는 것이 아니라 객체를 인스턴스화하는 것이 목적이기 때문입니다. 반면에 추상 클래스는 생성자를 가질 수 있어 공통 속성을 초기화하거나 하위 클래스 생성 시 설정 작업을 수행할 수 있습니다.

인터페이스와 추상 클래스 중 어느 것을 사용할지는 귀하의 특정 요구사항과 설계 목표에 따라 다릅니다. 모든 구현하는 클래스가 특정 메서드를 따르도록 강제하고 싶다면 인터페이스를 사용하고, 여러 클래스 간에 기본 동작이나 속성을 공유하고 싶다면 추상 클래스를 사용해야 합니다.

이제 PHP에서 추상 클래스에 대한 소개가 끝났습니다! 이 튜토리얼이 여러분한들 추상 클래스의 작동 방식과 어떻게 사용할 수 있는지 잘 이해할 수 있기를 바랍니다. 연습이 완벽을 이루는 열쇠이므로, 계속 코딩하고 추상 클래스를 실험하여 더 익숙해지세요. 행복한 코딩을!

Credits: Image by storyset