Menu
Coddy logo textTech

접근 제어자 심층 이해

Coddy PHP 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 91개 중 39번째.

이제 세 가지 접근 제한자를 이해했으므로, 상속 상황에서 이들이 어떻게 동작하는지 살펴보겠습니다. 핵심은 protected 멤버는 자식 클래스에서 접근할 수 있게 되는 반면, private 멤버는 자식 클래스에서도 숨겨진 상태로 남는다는 것입니다.

<?php
class Vehicle {
    public $brand;
    protected $engineType;
    private $serialNumber;
    
    public function __construct($brand, $engine, $serial) {
        $this->brand = $brand;
        $this->engineType = $engine;
        $this->serialNumber = $serial;
    }
    
    private function getSerial() {
        return $this->serialNumber;
    }
    
    protected function getEngineInfo() {
        return $this->engineType;
    }
}

class Car extends Vehicle {
    public function getDetails() {
        return $this->brand . " - " . $this->getEngineInfo();
        // $this->serialNumber는 오류를 발생시킬 것입니다 - private!
        // $this->getSerial()도 실패할 것입니다 - private 메서드!
    }
}

$car = new Car("Toyota", "V6", "ABC123");
echo $car->getDetails();

출력:

Toyota - V6

Car 클래스는 $brand(public)에 액세스하고 getEngineInfo()(protected)를 호출할 수 있지만, $serialNumber 또는 getSerial()에는 액세스할 수 없습니다. 이러한 항목은 Vehicle에 private이기 때문입니다. 이러한 구분을 통해 일부 내부 세부 정보를 자식 클래스와 공유하면서 다른 정보는 완전히 숨길 수 있습니다.

핵심 요점: 자식 클래스가 내부 데이터나 메서드에 액세스해야 할 때는 protected를 사용하고, 자식 클래스조차 특정 구현 세부 사항에 접근해서는 안 될 때는 private를 사용하세요.

challenge icon

챌린지

쉬움

상속 전반에서 access modifiers가 어떻게 동작하는지 살펴보는 device management system을 만들어 보겠습니다. 다양한 visibility level의 properties를 가진 기본 Device class를 만든 다음, 자식 class가 어떤 members에 access할 수 있고 cannot access하는지 보여 주는 Smartphone class로 확장합니다.

코드를 세 개의 파일로 구성합니다.

  • Device.php: 다양한 수준의 data sensitivity를 가진 electronic devices를 나타내는 Device class를 만듭니다. 다음을 포함합니다.
    • manufacturer name을 위한 public property $brand
    • internal identification을 위한 protected property $modelNumber
    • factory-only data를 위한 private property $manufacturingCode
    constructor는 세 값을 모두 받아야 합니다. manufacturing code를 반환하는 private method getManufacturingCode()를 추가합니다. "Model: [modelNumber]"를 반환하는 public method getModelInfo()를 추가합니다. 마지막으로 "[brand]-[manufacturingCode]"를 반환하는 public method getFullCode()를 추가합니다. 이를 통해 class 자체가 자신의 private members에 access할 수 있음을 보여 줍니다.
  • Smartphone.php: Device를 extends하는 Smartphone class를 만듭니다. Device file을 포함합니다. constructor는 brand, modelNumber, manufacturingCode, operating system name을 받아야 합니다. 처음 세 값을 사용해 parent constructor를 Call한 다음, OS를 private property에 저장합니다. "[brand] [modelNumber] running [os]"를 반환하는 public method getDeviceDetails()를 추가합니다. public $brand에는 directly access할 수 있고 protected $modelNumber에도 access할 수 있지만, private $manufacturingCode에는 directly access할 수 없다는 점에 주목하세요. 대신 inherited public method getFullCode()를 사용해야 합니다.
  • main.php: Smartphone file을 포함합니다. 네 개의 inputs, 즉 brand name, model number, manufacturing code, operating system을 받습니다. 이 값들로 Smartphone instance를 Create합니다. 세 줄을 Print합니다.
    • getDeviceDetails()를 Call한 결과
    • inherited getModelInfo() method를 Call한 결과
    • inherited getFullCode() method를 Call한 결과

이 challenge는 핵심적인 차이를 강조합니다. Smartphone class는 Device에서 inherited된 protected $modelNumber를 자유롭게 사용할 수 있지만, private $manufacturingCodegetManufacturingCode()는 완전히 hidden 상태로 남아 있습니다. 즉, Device가 노출하도록 선택한 public interface를 통해서만 access할 수 있습니다.

직접 해보기

<?php
require_once 'Smartphone.php';

// 입력 읽기
$brand = trim(fgets(STDIN));
$modelNumber = trim(fgets(STDIN));
$manufacturingCode = trim(fgets(STDIN));
$os = trim(fgets(STDIN));

// TODO: 입력 값으로 Smartphone 인스턴스 생성

// TODO: getDeviceDetails()의 결과 출력

// TODO: 상속된 getModelInfo() 메서드의 결과 출력

// TODO: 상속된 getFullCode() 메서드의 결과 출력
?>
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 PHP 컴파일러