📚 PHP 중급 - 5주차: PHP 객체 지향 프로그래밍 (OOP) 기초 - 04 상속 (extends)

2025. 8. 1. 13:33프로그램/PHP 중급

📚 PHP 중급 - 5주차: PHP 객체 지향 프로그래밍 (OOP) 기초 - 04 상속 (extends)

📚 PHP 중급 - 5주차: PHP 객체 지향 프로그래밍 (OOP) 기초 - 04 상속 (extends)

PHP 객체 지향 프로그래밍(OOP)에서 상속(Inheritance)은 기존 클래스(부모 클래스 또는 슈퍼 클래스)의 속성(property)과 메서드(method)를 새로운 클래스(자식 클래스 또는 서브 클래스)가 물려받아 재사용하거나 확장할 수 있게 해주는 강력한 기능입니다. 이를 통해 코드의 재사용성을 높이고, 유지보수성을 향상시키며, 계층적인 클래스 구조를 만들 수 있습니다. PHP에서는 extends 키워드를 사용하여 상속을 구현합니다.


상속의 개념 및 장점

상속은 현실 세계의 '부모-자식' 관계와 유사합니다. 자식은 부모의 유전자나 특성을 물려받듯이, 자식 클래스는 부모 클래스의 멤버(속성, 메서드)를 물려받습니다.

상속의 주요 장점:

  • 코드 재사용성: 부모 클래스에 정의된 코드를 여러 자식 클래스에서 재사용할 수 있으므로, 중복 코드를 줄이고 개발 시간을 단축할 수 있습니다.
  • 유지보수성 향상: 공통된 기능을 부모 클래스에 모아두면, 해당 기능의 변경이 필요할 때 부모 클래스만 수정하면 되므로 유지보수가 용이해집니다.
  • 확장성: 부모 클래스의 기능을 그대로 사용하거나, 필요에 따라 새로운 기능(속성, 메서드)을 추가하거나 기존 기능을 재정의(오버라이딩)하여 확장할 수 있습니다.
  • 계층 구조 구축: 클래스 간에 논리적인 계층 관계를 설정하여 시스템의 구조를 명확하게 하고 이해도를 높일 수 있습니다.

extends 키워드를 사용한 상속 구현

PHP에서 extends 키워드를 사용하여 상속 관계를 설정합니다.

PHP
 
<?php
// 부모 클래스 (Parent Class / Super Class)
class Animal {
    public $name; // 동물 이름

    public function __construct($name) {
        $this->name = $name;
        echo "{$this->name}이(가) 태어났습니다.". PHP_EOL;
    }

    public function eat() {
        echo "{$this->name}이(가) 먹이를 먹습니다.". PHP_EOL;
    }

    public function sleep() {
        echo "{$this->name}이(가) 잠을 잡니다.". PHP_EOL;
    }
}

// 자식 클래스 (Child Class / Sub Class) - Animal 클래스를 상속받음
class Dog extends Animal {
    public function bark() {
        echo "{$this->name}이(가) 멍멍 짖습니다!". PHP_EOL;
    }

    // 부모 클래스의 메서드를 재정의 (오버라이딩)할 수도 있습니다.
    public function eat() {
        echo "{$this->name}이(가) 사료를 먹습니다.". PHP_EOL; // 부모의 eat()과 다르게 동작
    }
}

class Cat extends Animal {
    public function meow() {
        echo "{$this->name}이(가) 야옹야옹 웁니다.". PHP_EOL;
    }
}

// Dog 객체 생성 및 사용
$dog = new Dog("바둑이"); // Animal의 __construct 호출
$dog->eat();             // Dog에서 오버라이딩된 eat() 호출
$dog->sleep();           // Animal의 sleep() 호출
$dog->bark();            // Dog의 bark() 호출

echo PHP_EOL;

// Cat 객체 생성 및 사용
$cat = new Cat("나비"); // Animal의 __construct 호출
$cat->eat();             // Animal의 eat() 호출
// $cat->get_name(); // Error: Call to undefined method Cat::get_name()
$cat->sleep();           // Animal의 sleep() 호출
$cat->meow();            // Cat의 meow() 호출
?>

코드 설명:

  • Animal 클래스는 name 속성과 __construct(), eat(), sleep() 메서드를 가지고 있습니다. 이들이 부모 클래스의 공통적인 멤버입니다.
  • Dog 클래스는 extends Animal을 통해 Animal 클래스를 상속받습니다.
  • Dog 클래스는 bark()라는 자신만의 고유한 메서드를 가집니다.
  • Dog 클래스는 부모 클래스의 eat() 메서드를 재정의(오버라이딩)하여 자신만의 방식으로 동작하도록 변경했습니다.
  • Cat 클래스도 extends Animal을 통해 Animal 클래스를 상속받습니다.
  • Cat 클래스는 meow()라는 자신만의 고유한 메서드를 가집니다.
  • Cat 클래스는 eat() 메서드를 오버라이딩하지 않았으므로, Animal 클래스의 eat() 메서드를 그대로 사용합니다.

자식 클래스에서 부모 클래스 멤버 접근: parent 키워드

자식 클래스 내부에서 부모 클래스의 메서드를 호출하거나, 부모 클래스의 속성에 접근해야 할 때가 있습니다. 이때 parent 키워드를 사용합니다.

PHP
 
<?php
class ParentClass {
    protected $message = "부모 클래스의 메시지입니다.";

    public function __construct() {
        echo "ParentClass 생성자 호출". PHP_EOL;
    }

    public function displayMessage() {
        echo $this->message. PHP_EOL;
    }
}

class ChildClass extends ParentClass {
    public function __construct() {
        // 부모 클래스의 생성자를 호출
        parent::__construct();
        echo "ChildClass 생성자 호출". PHP_EOL;
    }

    public function displayParentMessage() {
        // 부모 클래스의 속성 접근 (protected 일 경우)
        echo "자식 클래스에서 접근한 부모 메시지: " . $this->message . PHP_EOL;
    }

    public function callParentMethod() {
        // 부모 클래스의 메서드 호출
        parent::displayMessage();
    }
}

$child = new ChildClass();
$child->displayParentMessage();
$child->callParentMethod();
?>

코드 설명:

  • ChildClass의 __construct() 메서드에서 parent::__construct()를 호출하여 부모 클래스의 생성자가 실행되도록 했습니다. (자식 클래스에 생성자가 정의되면 부모 생성자가 자동으로 호출되지 않으므로, 명시적으로 호출해야 합니다.)
  • displayParentMessage() 메서드에서는 protected로 선언된 부모의 message 속성에 $this->message로 직접 접근할 수 있음을 보여줍니다. (private은 접근 불가)
  • callParentMethod() 메서드에서는 parent::displayMessage()를 통해 부모 클래스의 displayMessage() 메서드를 호출합니다.

상속과 접근 제어자 (public, private, protected)

상속 관계에서 접근 제어자는 다음과 같이 동작합니다.

  • public: 부모 클래스의 public 멤버는 자식 클래스 내부와 외부에서 모두 접근할 수 있습니다.
  • protected: 부모 클래스의 protected 멤버는 해당 클래스 내부와 해당 클래스를 상속받은 자식 클래스에서만 접근할 수 있습니다. 클래스 외부에서는 접근할 수 없습니다.
  • private: 부모 클래스의 private 멤버는 오직 해당 클래스 내부에서만 접근할 수 있습니다. 자식 클래스에서도 private 멤버에는 직접 접근할 수 없습니다. 만약 자식 클래스에서 부모의 private 속성에 접근해야 한다면, 부모 클래스에 정의된 public 또는 protected Getter/Setter 메서드를 통해서만 가능합니다.
PHP
 
<?php
class BaseClass {
    public $publicVar = "Public 변수";
    protected $protectedVar = "Protected 변수";
    private $privateVar = "Private 변수 (접근 불가)";

    public function getPrivateVar() {
        return $this->privateVar;
    }
}

class DerivedClass extends BaseClass {
    public function showInheritedVars() {
        echo "Public: " . $this->publicVar . PHP_EOL;       // 접근 가능
        echo "Protected: " . $this->protectedVar . PHP_EOL; // 접근 가능
        // echo "Private: " . $this->privateVar . PHP_EOL;  // 오류: private은 자식도 직접 접근 불가
        echo "Private (via Getter): " . $this->getPrivateVar() . PHP_EOL; // public getter를 통해 접근
    }
}

$derived = new DerivedClass();
$derived->showInheritedVars();

echo $derived->publicVar . PHP_EOL; // 외부에서 public 접근 가능
// echo $derived->protectedVar . PHP_EOL; // 오류: 외부에서 protected 접근 불가
// echo $derived->privateVar . PHP_EOL;   // 오류: 외부에서 private 접근 불가
?>

최종 클래스: final 키워드

클래스나 메서드 앞에 final 키워드를 붙이면, 해당 클래스는 더 이상 상속될 수 없거나, 해당 메서드는 자식 클래스에서 오버라이딩될 수 없도록 제한할 수 있습니다.

PHP
 
<?php
final class CannotBeExtended {
    public function sayHello() {
        echo "확장될 수 없는 클래스입니다.". PHP_EOL;
    }
}

// class MyClass extends CannotBeExtended {} // 오류: final 클래스는 상속 불가

class BaseWithFinalMethod {
    public function doSomething() {
        echo "일반 메서드". PHP_EOL;
    }

    final public function doFinalSomething() {
        echo "오버라이딩 불가 메서드". PHP_EOL;
    }
}

class DerivedWithFinalMethod extends BaseWithFinalMethod {
    public function doSomething() {
        echo "자식에서 오버라이딩된 일반 메서드". PHP_EOL;
    }

    // public function doFinalSomething() {} // 오류: final 메서드는 오버라이딩 불가
}

$obj = new DerivedWithFinalMethod();
$obj->doSomething();
$obj->doFinalSomething();
?>

PHP에서 상속은 객체 지향 프로그래밍의 핵심 원칙 중 하나로, 코드 재사용성과 유지보수성을 크게 향상시킵니다. 적절한 상속과 접근 제어자 사용은 견고하고 확장 가능한 시스템을 구축하는 데 필수적입니다.

 

중국/해외 유투브,카톡,차이나 VPN. 1일 무료이용체험

https://xn--299ao67b9qbmsf04c.net/

 

VPN 5,500원 / IP교체 1,100원 / 유동프록시 22,000원 | LuzenVPN 루젠VPN

국내최저가 고정IP서비스,유동프록시(IP4000개이상제공),PPTP,L2TP,IPSec,OpenVPNVPN,통신사VPN,VPN프로그램,고정IP,고정아이피,PPTP,저렴한VPN,리니지MVPN,리니지VPN,아이온VPN,던파VPN,유동프록시,유동PROXY,바이

vpn.luzensoft.com