PHP OOP - swkim0128/PARA GitHub Wiki


type: PHP archive: false

상속


상속(inheritance)읎란?

상속(inheritance)읎란 Ʞ졎의 큎래슀에 êž°ëŠ¥ì„ 추가하거나 재정의하여 새로욎 큎래슀륌 만드는 것을 의믞합니닀.
읎러한 상속은 캡슐화, 추상화와 ë”불얎 객첎 지향 프로귞래밍을 구성하는 쀑요한 특징 쀑 하나입니닀.

상속을 읎용하멎 êž°ì¡Žì— 정의되얎 있는 큎래슀의 몚든 프로퍌티와 메소드륌 ë¬Œë €ë°›ì•„, 새로욎 큎래슀륌 생성합니닀.
읎때 Ʞ졎에 믞늬 정의되얎 있던 íŽëž˜ìŠ€ë¥Œ 부몚 íŽëž˜ìŠ€(parent class) 또는 상위 큎래슀(super class)띌고 합니닀.
귞늬고 상속을 통핎 새롭게 작성되는 íŽëž˜ìŠ€ë¥Œ 자식 íŽëž˜ìŠ€(child class) 또는 하위 íŽëž˜ìŠ€(sub class)띌고 합니닀.

상속(inheritance)

PHP에서는 상속(inheritance)을 통핎 큎래슀 간의 계잵 ꎀ계륌 만듀 수 있습니닀.
자식(child) 큎래슀는 ë¶€ëªš(parent) 큎래슀의 몚든 public, protected 멀버륌 상속받게 됩니닀.

PHP에서는 extend 킀워드륌 사용하여 ìƒì†ì„ 정의합니닀.

닀음 예제는 A 큎래슀륌 상속받는 B 큎래슀륌 정의하는 예제입니닀.

class B extends A {
    B íŽëž˜ìŠ€ë§Œì˜ í”„로퍌티와 ë©”소드;
}

위의 예제에서 B 큎래슀는 A 큎래슀의 자식 큎래슀가 되고, 반대로 A 큎래슀는 B 큎래슀의 부몚 큎래슀가 됩니닀.
B 큎래슀는 A 큎래슀의 private 멀버륌 제왞한 몚든 프로퍌티와 ë©”소드륌 ìƒì†ë°›ì•„ ì‚¬ìš©í•  수 있습니닀.
여Ʞ에 필요하닀멎 자신만의 프로퍌티와 메소드륌 ì¶”가할 수 ìžˆìŠµë‹ˆë‹€.

읎렇게 상속을 읎용하멎 Ʞ졎에 작성된 큎래슀륌 손쉜게 재활용할 수 있습니닀.
또한, 공통적읞 부분은 부몚 íŽëž˜ìŠ€ì— ë¯žëЬ 작성하여, 자식 íŽëž˜ìŠ€ì—ì„œ ì€‘복되는 부분을 제거할 수도 있습니닀.

PHP에서는 둘 읎상의 부몚 큎래슀에서 프로퍌티와 ë©”소드륌 ìƒì†ë°›ì„ 수는 없습니닀.
하나의 부몚 큎래슀가 ì—¬ëŸ¬ 자식 큎래슀륌 가질 수는 있지만, 자식 큎래슀는 였직 부몚 큎래슀륌 하나만 ê°€ì§ˆ 수 있습니닀.

였버띌읎딩(overriding)

였버띌읎딩(overriding)읎란 ìŽë¯ž 정의된 메소드륌 같은 읎늄의 메소드로 ë‹€ì‹œ 정의하는 것읎띌고 할 수 있습니닀.
슉, 메소드 였버띌읎딩읎란 상속받은 부몚 íŽëž˜ìŠ€ì˜ 메소드륌 재정의하여 사용하는 것을 의믞합니닀.

PHP에서는 부몚 큎래슀의 메소드와 읎늄만 작성하멎, 핎당 메소드륌 였버띌읎딩할 수 있습니닀.

class A
{
    public $property = "class A";
    public function showProperty()
    {
        echo $this->property."<br>";
    }
}

class B extends A                    // 큎래슀 A륌 상속 받음.
{
    public $property = "class B";
    public function showProperty()   // 큎래슀 A의 메소드륌 였버띌읎딩
    {
        echo "hello ".$this->property."<br>";
    }
}

$a = new A();
$a->showProperty();                  // 큎래슀 A의 메소드 혞출
$b = new B();
$b->showProperty();                  // 큎래슀 B의 메소드 혞출

위의 예제에서 ìžì‹ 큎래슀읞 B 큎래슀는 ë¶€ëªš 큎래슀읞 A 큎래슀로부터 상속받은 showProperty() 메소드륌 였버띌읎딩하여 사용합니닀.
따띌서 B 큎래슀의 읞슀턎슀읞 $b에서 showProperty() 핚수륌 혞출하멎, 였버띌읎딩된 B 큎래슀의 showProperty() 핚수가 혞출됩니닀.

정적 멀버


static 킀워드

큎래슀륌 정의할 때 static 킀워드륌 사용한 í”„로퍌티와 ë©”소드는 핎당 큎래슀의 읞슀턎슀륌 생성하지 않아도 접귌할 수 있게 됩니닀.
읎러한 프로퍌티와 ë©”소드륌 정적 ë©€ë²„(static member)띌고 합니닀.

읎러한 정적 멀버의 특징은 닀음곌 같습니닀.

  1. static 킀워드로 선얞된 정적 프로퍌티는 ìžìŠ€í„ŽìŠ€í™”ëœ 객첎에서는 접귌할 수 없습니닀.
  2. static 킀워드로 선얞된 정적 메소드는 읞슀턎슀화된 객첎에서도 접귌할 수 있습니닀.
  3. 정적 ë©”소드 낎에서는 $this 의사 ë³€ìˆ˜ë¥Œ 사용할 수 없습니닀.
class StaticMember
{
    public static $staticProperty = "static property";
    public static function showProperty()
    {
        echo self::$staticProperty;."<br>";
    }
}

echo StaticMember::showProperty();  // 혞출 가능
echo StaticMember::$staticProperty; // ì ‘ê·Œ 가능

$var = new StaticMember();          // 읞슀턎슀 생성
echo $var->showProperty();          // 혞출 가능
//echo $var->$staticProperty;       // ì ‘ê·Œ 불가능

위의 예제에서 정적 메소드읞 showProperty() 메소드에서는 자신을 가늬킀는 $this 의사 변수륌 사용할 수 없습니닀.

따띌서 self 킀워드와 핚께 범위 지정 연산자륌 사용하여 프로퍌티에 접귌하고 있습니닀.

또한, 생성된 읞슀턎슀에서는 정적 프로퍌티에 접귌할 수 없음을 볎여죌고 있습니닀.

범위 지정 연산자(::)

큎래슀의 프로퍌티나 메소드에 접귌하Ʞ 위핎서는 읞슀턎슀륌 생성하고, 화삎표 연산자(->)륌 사용핎알 합니닀.

하지만 닚순히 큎래슀의 정의 낎에서 프로퍌티나 메소드륌 사용하고 싶을 때는 범위 지정 연산자(::)륌 사용할 수 있습니닀.

범위 지정 연산자(::)는 큎래슀의 상수, ì •적(static) 멀버 ë˜ëŠ” 재정의된 멀버에 접귌할 수 있게 핎쀍니닀.

큎래슀의 정의 왞부에서 위와 같은 멀버에 접귌할 때는 큎래슀의 읎늄을 사용핎알 합니닀.

echo OtherClassName::CONSTANT;

또한, 닀음 킀워드륌 ì‚¬ìš©í•˜ë©Ž íŽëž˜ìŠ€ì˜ 정의 낎에서 특정 프로퍌티나 메소드에 접귌할 수 있습니닀.

  1. self : 자Ʞ 자신에 접귌할 때
  2. parent : 부몚 큎래슀에 접귌할 때
echo self::$property;
echo parent::CONSTANT;

읞터페읎슀


추상 메소드(abstract method)

추상 메소드(abstract method)란 자식 íŽëž˜ìŠ€ì—ì„œ 반드시 였버띌읎딩핎알만 사용할 수 있는 메소드륌 의믞합니닀.
읎러한 추상 메소드는 선얞부만읎 졎재하며, 구현부는 작성되얎 있지 않습니닀.
바로 읎 작성되얎 있지 않은 구현부륌 자식 큎래슀에서 였버띌읎딩하여 사용하는 것입니닀.

Important

묞법abstract 접귌제얎자 function ë©”소드읎늄();

추상 큎래슀(abstract class)

PHP에서는 최소한 하나 읎상의 추상 메소드륌 포핚하는 큎래슀륌 ì¶”상 큎래슀(abstract class)띌고 합니닀.
읎러한 추상 큎래슀는 객첎 지향 프로귞래밍에서 쀑요한 특징읞 닀형성을 가진 메소드의 집합을 정의할 수 있게 핎쀍니닀.
슉, 반드시 사용되얎알 하는 메소드륌 추상 큎래슀에 추상 메소드로 선얞핎 놓윌멎, 읎 큎래슀륌 상속받는 ëªšë“  큎래슀에서는 읎 추상 메소드륌 반드시 재정의핎알 합니닀.

abstract class AbstractClass            // 추상 큎래슀
{
    abstract protected function move(); // 추상 메소드
    abstract protected function stop();

    public function start() // 공통 메소드
    {
        ...
    }
}

읎러한 추상 큎래슀는 동작읎 정의되얎 있지 않은 추상 메소드륌 포핚하고 있윌므로, 읞슀턎슀륌 생성할 수 ì—†ìŠµë‹ˆë‹€.

추상 큎래슀는 뚌저 상속을 통핎 자식 íŽëž˜ìŠ€ë¥Œ 만듀고, 만든 자식 íŽëž˜ìŠ€ì—ì„œ 추상 큎래슀의 몚든 추상 메소드륌 였버띌읎딩하고 나서알 ë¹„로소 자식 íŽëž˜ìŠ€ì˜ ìžìŠ€í„ŽìŠ€ë¥Œ 생성할 수 있게 됩니닀.

읞터페읎슀(interface)

PHP에서 읞터페읎슀(interface)란 닀륞 큎래슀륌 작성할 때 Ʞ볞읎 되는 틀을 제공하멎서, 닀륞 큎래슀 사읎의 쀑간 맀개 역할도 닎당하는 음종의 추상 큎래슀륌 의믞합니닀.

읞터페읎슀륌 사용하멎 큎래슀가 반드시 구현핎알 할 메소드가 얎떻게 동작하는지륌 알 필요 없읎 닀륞 부분의 윔드륌 작성할 수 있습니닀.

읎러한 읞터페읎슀는 메소드의 구현부가 정의되얎 있지 않은 추상 메소드듀로 구성되얎 있윌며, 낎부의 몚든 추상 메소드는 public 메소드입니닀.

PHP에서는 interface 킀워드륌 사용하여 읞터페읎슀륌 정의합니닀.

Important

묞법interface ìží„°íŽ˜ìŽìŠ€ìŽëŠ„ {    êµ¬í˜„í•  ë©”소드;}

읎렇게 정의된 읞터페읎슀는 implements 킀워드륌 사용하여 구현할 수 있습니닀.
읞터페읎슀륌 구현하는 큎래슀는 읞터페읎슀의 몚든 메소드륌 구현핎알 합니닀.
읎렇게 구현되는 메소드는 읞터페읎슀에서 정의된 형태와 완전히 같은 형태로 정의되얎알 합니닀.

읞터페읎슀의 몚든 메소드는 큎래슀 안에서 몚두 구현되얎알 합니닀.

interface Transport              // 읞터페읎슀의 정의
{
    public function move();      // 구현할 메소드
    public function stop();
}

class Car implements Transport   // Transport 읞터페읎슀륌 구현하는 Car 큎래슀
{
    function move()              // 메소드 구현
    {
        ...
    }

    function stop()              // 메소드 구현
    {
        ...
    }
}

# 읞터페읎슀(interface)도 큎래슀처럌 extends 킀워드륌 사용하여 상속받을 수 있습니닀.
interface Transport                  // 읞터페읎슀의 정의
{
    public function move();          // 구현할 메소드
    public function stop();          // 구현할 메소드
}

interface Overland extends Transport // Transport 읞터페읎슀륌 상속받는 Overland 읞터페읎슀
{
    public function highpass();      // 구현할 메소드
}

class Car implements Overload        // Overland 읞터페읎슀륌 구현하는 Car 큎래슀
{
    function move()                  // 메소드 구현
    {
        ...
    }

    function stop()                  // 메소드 구현
    {
        ...
    }

    function highpass()              // 메소드 구현
    {
        ...
    }
}

Important

PHP 읞터페읎슀는 큎래슀와는 달늬 각각의 읞터페읎슀륌 쉌표(,)로 구분하여 여러 개의 읞터페읎슀륌 동시에 상속받을 수 있습니닀.

였버로딩


닀형성(polymorphism)

닀형성(polymorphism)읎란 하나의 프로퍌티가 ì—¬ëŸ¬ 가지 상태륌 가질 수 있는 것을 의믞합니닀.

PHP에서는 읎러한 닀형성을 였버로딩(overloading)곌 지연 정적 바읞딩(late static bindings)을 통핎 구현하고 있습니닀.

닀형성은 상속, 추상화와 ë”불얎 객첎 지향 프로귞래밍을 구성하는 쀑요한 특징 쀑 하나입니닀.

였버로딩(overloading)

닀륞 대부분의 객첎 지향 프로귞래밍 얞얎에서 였버로딩(overloading)은 ë§€ê°œë³€ìˆ˜ì˜ 개수와 타입을 달늬하여 ê°™ì€ 읎늄의 메소드륌 쀑복하여 정의하는 것을 의믞합니닀.
하지만 PHP에서는 닀륞 얞얎와는 달늬 프로퍌티나 메소드륌 동적윌로 '생성한닀'는 의믞로 ì˜€ë²„로딩을 사용합니닀.

읎렇게 동적윌로 생성된 멀버는 핎당 큎래슀의 맀직 메소드(magic method)륌 통핎 닀양한 형태로 처늬할 수 있습니닀.
읎때 였버로딩되는 ë©”소드는 반드시 public윌로 정의되얎알만 합니닀.

Important

맀직 메소드(magic method)란 PHP에서 특수한 Ʞ능을 위핎 믞늬 정의한 메소드륌 가늬킵니닀.읎러한 맀직 메소드는 ë©”소드 ìŽëŠ„ê³Œ 맀개변수, 반환 타입, í˜žì¶œì˜ 타읎밍만읎 정핎젞 있윌며, ê·ž 낎용은 사용자가 직접 작성하여 사용할 수 있습니닀.PHP에서 몚든 맀직 메소드의 읎늄은 두 개의 얞더슀윔얎(__)로 시작합니닀.

프로퍌티 였버로딩(property overloading)

PHP에서는 ì ‘ê·Œ 불가 í”„로퍌티(inaccessible property)륌 였버로딩하Ʞ 위핎 ë‹€ìŒê³Œ 같은 맀직 메소드륌 구현핎알 합니닀.

Important

맀직 메소드의 원형public void __set(string $name, mixed $value)public mixed __get(string $name)public bool __isset(string $name)public bool __unset(string $name)

  1. __set() 메소드는 ì ‘ê·Œ 불가 프로퍌티의 값을 섀정할 때 혞출됩니닀.
  2. __get() 메소드는 ì ‘ê·Œ 불가 프로퍌티의 값을 읜을 때 혞출됩니닀.
  3. __isset() 메소드는 ì ‘ê·Œ 불가 프로퍌티에 대핮 isset() 핚수나 empty() 핚수가 혞출될 ë•Œ 혞출됩니닀.
  4. __unset() 메소드는 ì ‘ê·Œ 불가 프로퍌티에 대핮 unset() 핚수가 혞출될 때 혞출됩니닀.

Important

접귌불가 프로퍌티(inaccessible property)란 현재 영역에서는 정의되얎 있지 않거나, ì ‘ê·Œ 제얎로 읞핎 볎읎지 않는 프로퍌티륌 의믞합니닀.

class PropertyOverloading
{
private $data = array(); // 였버로딩된 변수가 저장될 ë°°ì—Ž 생성
public $declared = 10;   // public윌로 선얞된 프로퍌티
private $hidden = 20;    // private로 선얞된 프로퍌티

public function __set($name$value)
{
    echo "$name í”„로퍌티륌 {$value}의 값윌로 생성합니닀!";
    $this->data[$name] = $value;
}

public function __get($name)
{
    echo "$name í”„로퍌티의 값을 읜습니닀!<br>";

    if (array_key_exists($name$this->data)) {
        return $this->data[$name];
    } else {
        return null;
    }
}
public function __isset($name)
{
    echo "$name í”„로퍌티가 섀정되얎 있는지 확읞합니닀!<br>";
    return isset($this->data[$name]);
}
public function __unset($name)
{
    echo "$name í”„로퍌티륌 핎지합니닀!";
    unset($this->data[$name]);
}
}

$obj = new PropertyOverloading(); // PropertyOverloading 객첎 생성

① $obj->prop = 1;              // 동적 프로퍌티 생성
② echo $obj->prop;             // 동적 프로퍌티에 ì ‘ê·Œ
③ var_dump(isset($obj->prop)); // 동적 프로퍌티로 isset() 핚수 혞출
④ unset($obj->prop);           // 동적 프로퍌티로 unset() 핚수 혞출
â‘€ var_dump(isset($obj->prop)); // 동적 프로퍌티로 isset() 핚수 혞출

⑥ echo $obj->declared// 선얞된 프로퍌티는 였버로딩을 사용하지 않음.
⑩ echo $obj->hidden;   // private로 선얞된 프로퍌티는 큎래슀 왞부에서 접귌할 수 없윌므로, 였버로딩을 사용핚.

위의 예제에서는 프로퍌티륌 였버로딩하Ʞ 위핎 __set(), __get(), __isset(), __unset() 메소드륌 구현하고 있습니닀.

①번 띌읞에서는 동적윌로 프로퍌티륌 생성하고, ②번 띌읞에서는 ê·ž 값에 접귌합니닀.

③곌 ⑀번 띌읞에서는 생성된 동적 프로퍌티륌 isset() 핚수에 읞수로 전달하고, ④번 띌읞에서는 unset() 핚수에 읞수로 전달합니닀.

읎때 ①번부터 ⑀번 띌읞까지의 몚든 동작은 앞서 구현한 ë„€ 가지 메소드가 ìƒí™©ì— 맞게 자동 혞출됚윌로썚 읎룚얎집니닀.

하지만 ⑥번 띌읞곌 같읎 음반적읞 방법윌로 ì„ ì–žëœ 프로퍌티에 접귌할 때는 __get() ë©”소드륌 í˜žì¶œí•˜ì§€ 않습니닀.

닀만, ⑊번 띌읞처럌 private로 선얞된 프로퍌티는 큎래슀 왞부에서는 접귌할 수 없윌므로, __get() 메소드륌 혞출하게 됩니닀.

Important

array_key_exists() 핚수는 읞수로 전달받은 킀가 핎당 배엎에 저장되얎 있윌멎 true륌 반환하고, 저장되얎 있지 않윌멎 false륌 반환하는 핚수입니닀.

메소드 였버로딩(method overloading)

PHP에서는 접귌불가 메소드(inaccessible method)륌 였버로딩하Ʞ 위핎 ë‹€ìŒê³Œ 같은 맀직 메소드륌 구현핎알 합니닀.

Important

맀직 메소드의 원형1. public mixed __call(string $name, array $arguments)2. public static mixed __callStatic(string $name, array $arguments)

  1. __call() 메소드는 큎래슀 영역에서 ì ‘ê·Œ 불가 메소드륌 혞출할 때 혞출됩니닀.

  2. __callStatic() 메소드는 정적(static) 영역에서 ì ‘ê·Œ 불가 메소드륌 혞출할 때 혞출됩니닀.

class MethodOverloading
{
    public function __call($name, $arguments)
    {
        echo join(", ", $arguments)."에서 ì ‘ê·Œ 불가 메소드륌 혞출합니닀!";
    }

    public static function __callStatic($name, $arguments)
    {
        echo join(", ", $arguments)."에서 ì ‘ê·Œ 불가 메소드륌 혞출합니닀!";
    }
}

$obj = new MethodOverloading();             // MethodOverloading 객첎 생성

① $obj->testMethod("큎래슀 영역");            // 큎래슀 영역에서 ì ‘ê·Œ 불가 메소드 혞출
② MethodOverloading::testMethod("정적 영역"); // 정적 영역에서 ì ‘ê·Œ 불가 메소드 혞출

위의 예제에서는 메소드륌 였버로딩하Ʞ 위핎 __call()곌 __callStatic() 메소드륌 구현하고 있습니닀.

①번 띌읞에서는 동적윌로 testMethod() 메소드륌 생성하고, 바로 ê·ž 값에 접귌합니닀.

읎때 큎래슀 영역에서 생성된 동적 메소드에 접귌하므로, 사용자가 구현한 __call() 메소드가 혞출됩니닀.

②번 띌읞에서는 MethodOverloading 큎래슀의 정적 영역에서 동적 메소드에 접귌합니닀.

읎때 정적 영역에서 생성된 동적 메소드에 접귌하므로, 사용자가 구현한 __callStatic() 메소드가 혞출됩니닀.

늊은 정적 바읞딩


바읞딩(binding)

바읞딩(binding)읎란 프로귞랚에 사용된 구성 요소의 싀제 값 또는 프로퍌티륌 결정짓는 행위륌 ì˜ë¯ží•©ë‹ˆë‹€.
예륌 듀얎 핚수륌 혞출하는 부분에서 싀제 핚수가 위치한 메몚늬륌 연결하는 것도 ë°”로 바읞딩입니닀.

읎러한 바읞딩은 크게 닀음곌 같읎 êµ¬ë¶„í•  수 있습니닀.

  1. 정적 바읞딩(static binding) : 싀행 시간 전에 음얎나고, 싀행 시간에는 변하지 않은 상태로 유지되는 바읞딩임.
  2. 동적 바읞딩(dynamic binding) : 싀행 시간에 읎룚얎지거나 싀행 시간에 변겜되는 바읞딩임.
    읎러한 동적 바읞딩은 ëŠŠì€ 바읞딩(late binding)읎띌고도 불늜니닀.

하지만 PHP에서는 정적 바읞딩곌 동적 바읞딩의 쀑간 정도 수쀀읞 늊은 정적 바읞딩(LSB)을 제공하고 있습니닀.

늊은 정적 바읞딩(late static bindings, LSB)

PHP 5.3.0부터 제공되는 늊은 정적 바읞딩(LSB)은 static 킀워드와 핚께 범위 지정 연산자(::)륌 사용하여 수행할 수 있습니닀.
늊은 정적 바읞딩은 마지막윌로 혞출한 ë¹„전송 혞출(non-forwarding call)의 큎래슀 읎늄을 저장하여 동작합니닀.
읎때 정적 메소드 í˜žì¶œì—ì„œëŠ” 범위 지정 연산자(::) 좌잡에 명시된 큎래슀 읎늄을 저장하며, 비정적 메소드 í˜žì¶œì—ì„œëŠ” 핎당 객첎의 큎래슀 읎늄을 저장합니닀.

static::은 ì •의된 큎래슀륌 컎파음 시간에 결정할 수 없고, 프로귞랚 싀행 시 ì „달되는 ì •볎로 ê²°ì •하므로 늊은 바읞딩입니닀.
또한, 정적 메소드 í˜žì¶œì—ë„ 사용할 수 있윌므로 정적 바읞딩읎Ʞ도 합니닀.

Important

범위 지정 연산자(::, scope resolution operator)는 큎래슀의 상수, 정적(static) 멀버 또는 재정의된 멀버에 접귌할 수 있도록 핎죌는 연산자입니닀.

정적 메소드 혞출에서의 늊은 정적 바읞딩

닀음 예제는 self 킀워드와 핚께 ë²”위 지정 연산자(::)륌 사용하여 정적 메소드륌 혞출하는 예제입니닀.

class A
{
    public static function className()
    {
        echo __CLASS__;
    }

    public static function printClass()
    {
        self::className();
    }
}

class B extends A
{
    public static function className()
    {
        echo __CLASS__;
    }
}

① B::printClass(); // A

위의 예제에서 ①번 띌읞의 싀행 결곌는 큎래슀 A륌 출력합니닀.

슉, 큎래슀 B에서 printClass() 메소드륌 혞출하지만, 읎 메소드는 íŽëž˜ìŠ€ A에서 정의되므로 큎래슀 A륌 출력하게 됩니닀.

읎처럌 현재 큎래슀륌 찞조하는 self::와 상수 __CLASS__는 사용하는 메소드가 얎디에 정의되얎 있는가에 따띌 ê·ž 값읎 결정됩니닀.

하지만 늊은 정적 바읞딩을 사용하멎, 큎래슀 B에서 혞출한 printClass() 메소드가 í˜„재 큎래슀로 큎래슀 B륌 찞조하게 할 수 있습니닀.

닀음 예제는 static 킀워드와 핚께 범위 지정 연산자(::)륌 사용하여 정적 메소드륌 혞출하는 예제입니닀.

class A
{
    public static function className()
    {
        echo __CLASS__;
    }

    public static function printClass()
    {
        static::className();
    }
}

class B extends A
{
    public static function className()
    {
        echo __CLASS__;
    }
}

① B::printClass(); // B

위의 예제에서 ①번 띌읞의 싀행 결곌는 큎래슀 B륌 출력합니닀.

printClass() 메소드가 큎래슀 A에서 정의되지만, 큎래슀 B에서 읎 메소드륌 혞출하므로 큎래슀 B륌 출력하게 됩니닀.

읎처럌 static 킀워드와 범위 지정 연산자(::)륌 핚께 사용하멎 늊은 정적 바읞딩을 수행할 수 있습니닀.

비정적 메소드 혞출에서의 늊은 정적 바읞딩

닀음 예제는 static 킀워드와 핚께 ë²”위 지정 연산자(::)륌 사용하여 비정적 ë©”소드륌 혞출하는 예제입니닀.

class A
{
    private function className()
    {
        echo __CLASS__."<br>";
    }

    public function printClass()
    {
①      $this->className();
②      static::className();
    }
}

class B extends A
{
    // className() 메소드는 큎래슀 B로 복사되므로,
    // className() 메소드의 유횚 범위는 여전히 큎래슀 A임.
}

class C extends A
{
    private function className()
    {
        // Ʞ졎의 className() 메소드가 읎 메소드로 대첎되므로,
        // className() 메소드의 유횚 범위는 읎제부터 큎래슀 C가 됚.
    }
}


$b = new B();
③ $b->printClass(); // A
                     // A

$c = new C();
④ $c->printClass(); // A
                     // Fatal error : Call to private method C::className() from context 'A'

위의 예제에서 className() 메소드는 큎래슀 A에서 처음윌로 정의됩니닀.

귞늬고서 큎래슀 B가 큎래슀 A륌 상속받지만, 큎래슀 B에서 className() 메소드륌 재정의하지는 않습니닀.

따띌서 className() 메소드의 유횚 범위는 여전히 큎래슀 A가 되며, ③번 띌읞의 결곌처럌 변수 $this나 static::은 몚두 큎래슀 A륌 가늬킀게 됩니닀.

하지만 큎래슀 C가 큎래슀 A륌 상속받윌멎서 className() 메소드륌 재정의합니닀.

따띌서 className() 메소드의 유횚 범위는 읎제부터 큎래슀 C로 변겜될 것입니닀.

귞러므로 ④번 띌읞의 결곌처럌 변수 $this는 여전히 큎래슀 A륌 가늬킀겠지만, static::은 큎래슀 C륌 가늬킀게 될 것입니닀.

⚠ **GitHub.com Fallback** ⚠