PHP5의 액세스 방법을 사용하면 클래스 멤버에 대한 액세스를 제한할 수 있습니다. 이는 PHP5의 새로운 기능이지만 많은 객체 지향 언어에서 오랫동안 존재해 왔습니다. 액세스 방법을 사용하면 안정적인 객체 지향 애플리케이션을 개발하고 재사용 가능한 객체 지향 클래스 라이브러리를 구축할 수 있습니다.
C++ 및 Java와 마찬가지로 PHP에는 공개, 비공개 및 보호라는 세 가지 액세스 방법이 있습니다. 액세스 방법을 지정하지 않으면 기본 액세스 방법을 제공할 수도 있습니다. 정적 멤버는 액세스 방법을 지정합니다. public static과 같은 액세스 방법은
클래스 외부의 모든 코드에서 공용 속성을 읽고 쓸 수 있습니다. 스크립트 어디에서나 공개 메소드를 호출하십시오. 이전 버전의 PHP에서는 모든 메소드와 속성이 공개되어 객체가 잘 구조화된 배열처럼 보입니다.
전용 멤버는 클래스 내부에서만 볼 수 있으며, 해당 속성이 있는 클래스 메서드 외부에서는 전용 속성의 값을 변경하거나 읽을 수 없습니다. 마찬가지로 동일한 클래스의 메서드만 전용 메서드를 호출할 수 있으며 상속된 하위 클래스는 상위 클래스의 전용 멤버에 액세스할 수 없습니다.
private 멤버는 클래스의 모든 멤버와 클래스 인스턴스에서 액세스할 수 있습니다. 예제 6.8을 보면 equals 메서드는 두 위젯을 비교합니다. == 연산자는 동일한 클래스의 두 개체를 비교하지만 이 예제에서는 각 개체 인스턴스가 고유 ID를 갖습니다. Equals 메소드가 다른 Widget 인스턴스의 비공개 속성에 어떻게 접근하는지 주목하세요. Java와 C 모두 이를 허용합니다.
목록 6.8 Private 멤버
클래스 위젯
{
비공개 $name;
비공개 $ 가격;
비공개 $id;
공개 함수 __construct($name, $price)
{
$this->이름 = $이름;
$this->price = floatval($price);
$this->id = uniqid();
}
//두 위젯이 동일한 공개 함수인지 확인합니다. equals($widget)
{
return(($this->name == $widget->name)AND ($this->가격 == $widget->가격));
}
}
$w1 = new Widget('Cog', 5.00);
$w2 = new Widget('Cog', 5.00);
$w3 = new Widget('기어', 7.00)
//TRUE
if($w1->같음($w2))
{
print("w1과 w2는 n이 같습니다.");
}
//거짓
if($w1->같음($w3))
{
print("w1과 w3은 n이 같습니다.");
}
//FALSE, == 비교 시 ID를 포함합니다.
if($w1 == $w2) //ID가 다르기 때문에 같지 않습니다.
{
print("w1과 w2는 n이 같습니다.");
}
?>
객체지향 프로그래밍을 처음 접한다면, 이 장의 시작 부분에서 논의한 캡슐화와 결합의 개념을 기억할 것입니다. 프라이빗 멤버는 데이터를 캡슐화하는 데 도움이 되며, 클래스 외부의 코드에서 액세스할 수 없도록 숨겨질 수도 있습니다. 또한 데이터 구조 외부의 코드가 내부 속성에 직접 액세스할 수 없는 경우에는 암시적 상관 관계가 없습니다.
물론 대부분의 비공개 속성은 여전히 외부 코드에서 공유될 수 있습니다. 해결책은 한 쌍의 공개 메소드를 사용하는 것입니다. 하나는 get(속성 값 가져오기)이고 다른 하나는 set(속성 값 설정)입니다. 생성자는 또한 속성에 대한 초기 값을 허용합니다. 이는 좁고 검증된 인터페이스를 통해 멤버 간의 통신이 이루어질 수 있도록 하며, 생성자가 강제 변환하는 방법에 대해 예제 6.8에서 참고하세요. 가격을 부동 소수점 숫자로 만듭니다(floadval()).
보호된(protected) 멤버는 동일한 클래스의 모든 메서드와 상속된 클래스의 모든 메서드에서 액세스할 수 있습니다. 공용 속성은 하위 클래스가 특정 속성에 의존하여 작성할 수 있도록 허용하므로 캡슐화 정신에 위배됩니다. 보호된 메서드를 사용하는 하위 클래스는 상위 클래스의 구조를 잘 알고 있어야 합니다. .
예제 6.9는 예제 6.8에서 개선되었으며 위젯의 Thing 하위 클래스를 포함합니다. 이제 Widget에는 getName이라는 보호된 메서드가 있습니다. Widget의 인스턴스가 보호된 메서드를 호출하려고 하면 오류가 발생합니다. $w1->getName()은 오류를 생성하지만 하위 클래스 사물의 getName 메서드는 이를 보호된 메서드로 호출할 수 있습니다. 물론 이 예제는 Widget::getName 메소드가 보호된다는 것을 증명하기에는 너무 간단합니다. 실제 상황에서 보호된 메소드를 사용하려면 객체의 내부 구조를 이해해야 합니다.
목록 6.9 보호된 멤버
클래스 위젯
{
비공개 $name;
비공개 $ 가격;
비공개 $id;
공개 함수 __construct($name, $price)
{
$this->이름 = $이름;
$this->price = floatval($price);
$this->id = uniqid();
}
//두 위젯이 동일한지 확인합니다.
공개 함수는 같음($widget)
{
return(($this->name == $widget->name)AND($this->가격 == $widget->가격));
}
보호된 함수 getName()
{
return($this->이름);
}
}
클래스 사물이 위젯을 확장함
{
비공개 $color;
공개 함수 setColor($color)
{
$this->color = $color;
}
공개 함수 getColor()
{
return($this->color);
}
공개 함수 getName()
{
return(부모::getName());
}
}
$w1 = new Widget('Cog', 5.00);
$w2 = 새로운 사물('코그', 5.00);
$w2->setColor('Yellow');
//TRUE (여전히!) 결과는 여전히 true입니다.
if($w1->같음($w2))
{
print("w1과 w2는 n이 같습니다.");
}
//코그 출력 코그 인쇄
print($w2->getName());
?>
하위 클래스는 상위 클래스 메서드를 재정의하여 메서드 액세스 방법을 변경할 수 있습니다. 그러나 여전히 몇 가지 제한 사항이 있습니다. public 클래스 멤버를 재정의하는 경우 해당 멤버는 해당 하위 클래스에서 공개 상태로 유지되어야 합니다. 보호된 멤버를 재정의하면 해당 멤버는 보호된 상태로 유지되거나 전용 멤버가 현재 클래스에서만 표시됩니다. 상위 클래스의 전용 멤버와 동일한 이름을 가진 멤버를 선언하면 현재 클래스에 다른 멤버가 생성되므로 기술적으로 전용 멤버를 재정의할 수 없습니다.
Final 키워드는 멤버 메서드에 대한 액세스를 제한하는 또 다른 방법입니다. 하위 클래스는 상위 클래스에서 final로 표시된 메서드를 재정의할 수 없으며 Final 키워드는 속성에 사용할 수 없습니다.