객체 인터페이스
개체 인터페이스를 사용하면 이러한 메서드를 구현하는 방법을 정의하지 않고도 클래스에서 구현해야 하는 메서드를 지정하는 코드를 만들 수 있습니다. 인터페이스는 클래스 및 특성과 네임스페이스를 공유하므로 동일한 이름을 사용할 수 없습니다.
인터페이스는 클래스와 같은 방식으로 정의되지만 class
키워드를 대체하는 interface
키워드로 정의되고 내용이 정의된 메소드는 없습니다.
인터페이스에 선언된 모든 메서드는 public이어야 합니다. 이것이 인터페이스의 특성입니다.
실제로 인터페이스는 두 가지 보완적인 목적을 제공합니다.
- 개발자가 동일한 인터페이스를 구현하기 때문에 상호 교환적으로 사용할 수 있는 다른 클래스의 개체를 만들 수 있도록 합니다. 일반적인 예는 여러 데이터베이스 액세스 서비스, 여러 지불 게이트웨이 또는 다른 캐싱 전략입니다. 다른 구현은 이를 사용하는 코드를 변경하지 않고도 교체할 수 있습니다.
- 함수 또는 메서드가 인터페이스를 준수하는 매개변수를 수락하고 작동하도록 허용하면서 객체가 수행할 수 있는 다른 작업이나 구현 방법에 신경 쓰지 않습니다. 이러한 인터페이스는 동작의 중요성을 설명하기 위해
Iterable
,Cacheable
,Renderable
등과 같이 이름이 지정되는 경우가 많습니다.
인터페이스는 이러한 메서드를 구현하기 위해 클래스를 구현하도록 요구하는 매직 메서드를 정의할 수 있습니다.
메모: 지원되지만 인터페이스에 생성자를 포함하지 않는 것이 좋습니다. 그렇게 하면 인터페이스를 구현하는 개체의 유연성이 크게 줄어듭니다. 또한 생성자는 상속 규칙에 따라 적용되지 않으므로 일관성이 없고 예기치 않은 동작이 발생할 수 있습니다.
implements
인터페이스를 구현하기 위해 implements
연산자가 사용됩니다. 인터페이스의 모든 메서드는 클래스 내에서 구현되어야 합니다. 그렇지 않으면 치명적인 오류가 발생합니다. 클래스는 원하는 경우 각 인터페이스를 쉼표로 구분하여 둘 이상의 인터페이스를 구현할 수 있습니다.
경고 클래스는 두 인터페이스의 메서드 선언이 동일한 경우에만 동일한 이름의 메서드를 정의하는 두 개의 인터페이스를 구현할 수 있습니다.
경고 인터페이스를 구현하는 클래스는 해당 매개변수에 인터페이스와 다른 이름을 사용할 수 있습니다. 그러나 PHP 8.0부터 언어는 명명된 인수를 지원하므로 호출자가 인터페이스의 매개변수 이름에 의존할 수 있습니다. 이러한 이유로 개발자는 구현되는 인터페이스와 동일한 매개변수 이름을 사용하는 것이 좋습니다.
메모: extends 연산자를 사용하여 인터페이스를 클래스처럼 확장할 수 있습니다.
메모: 인터페이스를 구현하는 클래스는 호환되는 서명을 사용하여 인터페이스의 모든 메서드를 선언해야 합니다.
Constants
인터페이스에 상수가 있을 수 있습니다. 인터페이스 상수는 클래스 상수와 똑같이 작동합니다. PHP 8.1.0 이전에는 이를 상속하는 클래스/인터페이스가 재정의할 수 없습니다.
Examples
예제 #1 인터페이스 예
<?php
// Declare the interface 'Template'
interface Template
{
public function setVariable($name, $var);
public function getHtml($template);
}
// Implement the interface
// This will work
class WorkingTemplate implements Template
{
private $vars = [];
public function setVariable($name, $var)
{
$this->vars[$name] = $var;
}
public function getHtml($template)
{
foreach($this->vars as $name => $value) {
$template = str_replace('{' . $name . '}', $value, $template);
}
return $template;
}
}
// This will not work
// Fatal error: Class BadTemplate contains 1 abstract methods
// and must therefore be declared abstract (Template::getHtml)
class BadTemplate implements Template
{
private $vars = [];
public function setVariable($name, $var)
{
$this->vars[$name] = $var;
}
}
?>
예제 #2 확장 가능한 인터페이스
<?php
interface A
{
public function foo();
}
interface B extends A
{
public function baz(Baz $baz);
}
// This will work
class C implements B
{
public function foo()
{
}
public function baz(Baz $baz)
{
}
}
// This will not work and result in a fatal error
class D implements B
{
public function foo()
{
}
public function baz(Foo $foo)
{
}
}
?>
예제 #3 다중 인터페이스 상속
<?php
interface A
{
public function foo();
}
interface B
{
public function bar();
}
interface C extends A, B
{
public function baz();
}
class D implements C
{
public function foo()
{
}
public function bar()
{
}
public function baz()
{
}
}
?>
예제 #4 상수가 있는 인터페이스
<?php
interface A
{
const B = 'Interface constant';
}
// Prints: Interface constant
echo A::B;
class B implements A
{
const B = 'Class constant';
}
// Prints: Class constant
// Prior to PHP 8.1.0, this will however not work because it was not
// allowed to override constants.
echo B::B;
?>
예제 #5 추상 클래스가 있는 인터페이스
<?php
interface A
{
public function foo(string $s): string;
public function bar(int $i): int;
}
// An abstract class may implement only a portion of an interface.
// Classes that extend the abstract class must implement the rest.
abstract class B implements A
{
public function foo(string $s): string
{
return $s . PHP_EOL;
}
}
class C extends B
{
public function bar(int $i): int
{
return $i * 2;
}
}
?>
예제 #6 확장과 구현을 동시에
<?php
class One
{
/* ... */
}
interface Usable
{
/* ... */
}
interface Updatable
{
/* ... */
}
// The keyword order here is important. 'extends' must come first.
class Two extends One implements Usable, Updatable
{
/* ... */
}
?>
인터페이스는 형식 선언과 함께 특정 개체에 특정 메서드가 포함되어 있는지 확인하는 좋은 방법을 제공합니다. instanceof 연산자 및 유형 선언을 참조하십시오.