Menu
Coddy logo textTech

final 키워드

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

상속과 메서드 오버라이딩은 유연성을 제공하지만, 때로는 특정 클래스나 메서드가 변경되지 않도록 방지해야 할 필요가 있습니다. final 키워드는 코드를 잠가서 특정 구현이 자식 클래스에 의해 수정되지 않도록 보장합니다.

메서드를 final로 지정하면, 어떤 자식 클래스도 이를 오버라이드할 수 없습니다:

<?php
class BankAccount {
    protected $balance;
    
    public function __construct($balance) {
        $this->balance = $balance;
    }
    
    final public function getAccountId() {
        return "ACC-" . spl_object_id($this);
    }
}

class SavingsAccount extends BankAccount {
    public function addInterest() {
        return $this->balance * 0.05;
    }
}

$account = new SavingsAccount(1000);
echo $account->getAccountId();

출력:

ACC-1

getAccountId() 메서드는 SavingsAccount 또는 다른 하위 클래스에서 오버라이드할 수 없습니다. 이는 모든 계좌 유형에서 일관되게 유지되어야 하는 중요한 기능을 보호합니다.

또한 클래스 전체를 final로 표시하여 상속을 방지할 수도 있습니다:

<?php
final class SecurityManager {
    public function authenticate($user) {
        return "Authenticating $user";
    }
}

$security = new SecurityManager();
echo $security->authenticate("admin");

출력:

Authenticating admin

어떤 클래스도 SecurityManager를 상속할 수 없습니다. 이는 보안에 민감한 클래스나 클래스 설계가 완료되어 수정되지 않아야 하는 경우에 유용합니다.

핵심 포인트: 상속은 허용하면서 오버라이딩을 방지하려면 메서드에 final을 사용하고, 상속 자체를 완전히 방지하려면 클래스에 사용하세요. 이것은 설계된 대로 정확하게 작동해야 하는 중요한 코드를 보호하기 위한 도구입니다.

challenge icon

챌린지

쉬움

final 키워드가 자식 클래스에 의해 중요한 기능이 수정되는 것을 어떻게 방지하는지 보여주는 문서 관리 시스템을 구축해 보겠습니다.

특정 보안 기능이 잠겨 있는 상태를 유지하면서 다양한 문서 유형을 관리하기 위해 함께 작동하는 세 개의 파일을 생성합니다:

  • Document.php — 모든 문서의 기반이 되는 Document 클래스를 정의합니다. 이 클래스는 public $title 속성과 protected $author 속성을 가져야 합니다. 생성자는 제목(title)과 저자(author)를 모두 받습니다. "Signed by: [author]"를 반환하는 final 메서드인 getSignature()를 포함하세요. 이 보안 기능은 자식 클래스에서 절대 변경되어서는 안 됩니다. 또한 "Document: [title]"을 반환하는 일반 getContent() 메서드를 추가하세요.
  • Report.phpDocument를 상속받는 Report 클래스를 정의합니다. 파일 상단에 Document 파일을 포함하세요. 이 클래스는 $department 속성을 추가합니다. 생성자는 제목, 저자, 부서(department)를 받아야 하며, 처음 두 개는 parent::__construct()를 사용하여 설정한 다음 부서를 설정합니다. getContent() 메서드를 오버라이드하여 "Report: [title] ([department])"를 반환하도록 합니다. Report 클래스는 final로 선언된 getSignature() 메서드를 변경할 수 없는 상태로 상속받습니다.
  • main.php — Report 파일을 포함하세요. 문서 제목, 저자 이름, 부서라는 세 가지 입력을 받게 됩니다. 이 값들로 Report 객체를 생성합니다. 첫 번째 줄에 getContent()의 결과를 출력하고, 두 번째 줄에 getSignature()의 결과를 출력하세요.

이 챌린지는 final 메서드가 어떻게 중요한 기능을 보호하는지 보여줍니다. 서명 생성 방식은 모든 문서 유형에서 일관되게 유지되는 반면, getContent()와 같은 다른 메서드는 각 자식 클래스에서 커스터마이징할 수 있습니다. Report는 콘텐츠가 표시되는 방식을 변경할 수 있지만, 서명 형식은 부모 클래스에서 고정됩니다.

치트 시트

final 키워드는 클래스나 메서드가 자식 클래스에 의해 수정되는 것을 방지합니다.

Final 메서드: 메서드를 final로 표시하여 자식 클래스가 이를 오버라이딩하는 것을 방지합니다:

<?php
class BankAccount {
    protected $balance;
    
    final public function getAccountId() {
        return "ACC-" . spl_object_id($this);
    }
}

class SavingsAccount extends BankAccount {
    // getAccountId()를 오버라이딩할 수 없습니다.
}

Final 클래스: 클래스 전체를 final로 표시하여 상속을 방지합니다:

<?php
final class SecurityManager {
    public function authenticate($user) {
        return "Authenticating $user";
    }
}

// 어떤 클래스도 SecurityManager를 확장(상속)할 수 없습니다.

상속은 허용하면서 특정 기능을 보호하려면 메서드에 final을 사용하고, 상속 자체를 완전히 방지하려면 클래스에 사용하세요. 이는 보안에 민감한 코드나 구현이 일관되게 유지되어야 할 때 유용합니다.

직접 해보기

<?php
require_once 'Report.php';

// 입력 읽기
$title = trim(fgets(STDIN));
$author = trim(fgets(STDIN));
$department = trim(fgets(STDIN));

// TODO: 입력 값을 사용하여 Report 객체 생성

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

// TODO: getSignature()의 결과 출력
?>
quiz icon실력 점검

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

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