2010-12-07 6 views
8

PHP에서 인터페이스를 정의하고 해당 인터페이스의 인스턴스를 만드는 팩토리 클래스를 정의하면 클라이언트 코드가 기본 클래스가 아닌 인터페이스 만 사용하도록 할 수있는 방법이 있습니까? 내 이해에서 클라이언트는 실제로 기본 클래스의 모든 공용 함수/필드를 사용할 수 있습니다.PHP의 인터페이스 목적은 무엇입니까?

<?php 
interface IMyInterface 
{ 
    public function doSomething(); 
} 
?> 

<?php 
class ConcreteImplOfMyInterface implements IMyInterface 
{ 
    const NotPartOfInterface = 'youcantseeme'; 

    public function doSomething() 
    { 
    } 
} 
?> 

<?php 
class MyInterfaceFactory 
{ 
    public static function createMyInterface() 
    { 
     return new ConcreteImplOfMyInterface(); 
    } 
} 
?> 

<?php 
function client() 
{ 
    $myInterface = MyInterfaceFactory::createMyInterface(); 
    return $myInterface::NotPartOfInterface; 
} 
?> 

답변

6

정적으로 입력 된 언어에서만 가능하며 PHP가 동적으로 입력되므로 짧은 대답은 불가능하다는 것입니다.

예를 들어 Java에서 createMyInterfaceIMyInterface을 반환 할 수 있으며이 개체에 대해 가능한 작업은 인터페이스 자체에 정의 된 작업입니다. 물론 객체는 실제로 유형이 ConcreteImplOfMyInterface이므로 다른 유형의 필드/메소드에 액세스하기 위해 언제든지 해당 유형으로 캐스팅 할 수 있습니다.

PHP에는 선언 된 유형이 없으므로 함수에서 반환하는 것은 단순히 "변수"일뿐입니다. 유형은 없습니다. 유형이 없기 때문에 모든 필드/메소드 조회는 동적이므로 객체에 "있는"모든 항목에 항상 액세스 할 수 있습니다.

어떤면에서는 인터페이스가 실제로 PHP와 같은 언어로 사용되는 데 제한이 있습니다. 인터페이스를 구현하는 모든 클래스는 모든 메소드를 구현해야하지만, 함수가 모든 메소드를 구현해야합니다. 첫째로, 근본적으로 아무 것도 전혀 보증하지 않습니다. 가장 좋은 방법은 instanceof을 사용하여 알 수없는 변수가 주어진 인터페이스를 구현하는지 확인하는 것입니다.

1

이 방법은 비공개 : 여기

은 예입니다.

return $myInterface.NotPartOfInterface; 

작동합니까? 나는 그것이해야한다고 생각하지 않는다. :: 연산자를 원한다고 생각합니다.

.은 문자열 연결에만 사용됩니다.

interface Printable{ 
    public function display(); 
} 

function display(Printable $obj){ 
    $obj->display(); 
} 

그것은 그 함수에 들어가는 모든 변수가 인쇄의 인스턴스 있어야합니다 : 인터페이스는 PHP에 좋은 이유

9

이입니다. 따라서, 당신은 당신이 그 기능을 사용하기를 원한다면 당신의 코드를 사용하는 누군가가 그 인터페이스를 구현하도록 강요합니다. 5.1 http://php.net/manual/en/language.oop5.typehinting.php

당신이 다른 반드시 누군가가 특정 메소드 나 클래스의 변수를 사용할 수 없습니다 확인하려면

PHP, 당신은 private으로 그 방법과 변수를 정의해야합니다. 이렇게하면 특정 클래스가 아닌 다른 클래스에서 사용할 수 없게됩니다. (클래스를 확장하는 클래스조차도 클래스를 사용할 수 없다.)

+0

좋은 물건을 위해 +1 – alex

+0

나는 OOP 접근 수정자를 알고 있고 PHP는 힌트를 가지고 있다는 것을 알고있다. 함수 리턴 타입에 타입 힌팅이 없다는 사실은 인터페이스가 저에게 무의미한 것처럼 보일 수 있습니다. 같은 논리적 구성 요소의 클래스가 서로 공용 메서드를 호출 할 수있게하려면 해당 구성 요소와 통신하는 유일한 방법 인 공용 인터페이스를 공개하기 위해 해당 구성 요소 전체를 원했습니다. PHP에서는 불가능 해 보입니다. – jameswelle

+0

흥미로운 점은 현재 클래스의 인스턴스에 대한 보호 된 개인 메소드/변수에 도달 할 수 있다는 것입니다. 예를 들어 User 클래스가 private 토큰 $ token을 가지고 있다면 User 클래스 안에 다음과 같은 메소드를 가질 수 있습니다 : public function changeToken (User $ user) {$ user-> token = '1234'; } – Joe

2

PHP는 동적 언어이므로 런타임시 클래스 멤버에 대한 모든 액세스가 해결된다는 것을 의미합니다. 즉, $ foo-> bar()를 호출하는 코드가 있고 bar()라는 메서드가있는 $ foo에 객체가있는 경우 호출 할 메서드 bar()가 아닌 경우에도 호출됩니다. 그러나 우연에 의해 같은 이름이 붙여진 다른 대상에 대한 다른 방법이 있습니다.

그러나 밝혔다되고, 당신이 기능은 특정 개체 동의하도록 입력 매개 변수를 사용하여 몇 가지 보호 기능을 제공 할 수 그러나

function doingSomething(IMyInterface $foo) { 
    $foo->doSomething(); 
} 

을, 당신은 여전히 ​​기능을 IMyInterface를 구현하고 쓰는 사람을 금지 할 수없는 IMyInterface를 받아들이지 만 그것을 마치 어떤 상위 클래스의 객체처럼 사용하십시오. 내가 말했듯이, 이것은 PHP가 동적 인 언어 때문입니다.

관련 문제