액세스를 제한하는 것 외에도 액세스 메서드는 서브클래스에서 어떤 메서드를 호출할지 또는 서브클래스에서 어떤 속성에 액세스할지 결정하며, 함수 호출과 함수 자체 간의 관계, 멤버 액세스와 변수 메모리 주소 간의 관계도 결정합니다.
컴퓨터 언어에서는 정적바인딩
과 동적 바인딩의 두 가지 주요 방법이 있습니다. 정적 바인딩은 프로그램이 실행되기 전에 발생하므로 런타임을 사용할 수 없습니다. PHP는 동적 언어이기 때문에 함수 호출과 함수 본문, 변수 및 블록을 대상으로 합니다. 그러나 동적 바인딩은
런타임 중에 생성된 액세스를
시뮬레이션할 수 있습니다. 요청은 런타임 시 사용 가능한 정보만 사용합니다.객체
지향 코드에서 동적 바인딩은 호출되는 메서드나 액세스되는 속성에 대한 결정이 액세스 범위가 아닌 클래스 자체를 기반으로 한다는 것을 의미합니다.
동적 바인딩을 사용하는 이전 버전 PHP의 함수 작업과 유사합니다. 즉, 메서드가 하위 클래스에서 재정의되고 하위 클래스의 인스턴스인 클래스 멤버에 액세스하면 멤버에 액세스하는 대신 하위 클래스 멤버에 액세스됩니다.
그림 1을 참조하세요.
이 코드는 "Hey! I am Son"을 출력합니다. 왜냐하면 PHP가 getSalutation을 호출할 때 이는 Father의 인사말을 덮어쓰는 것이기 때문입니다. 메소드를 재정의하면 유사한 방식으로 작동합니다.
하위 클래스에서도 액세스 모드가 protected에서 public으로 약화되지만 동적 바인딩은 계속 발생합니다.
접근 방법을 사용하는 원칙상 클래스 멤버에 대한 접근 제한을
강화하는 것은 불가능합니다. 따라서 접근 방법을 public에서 protected로 변경하는 것은 불가능합니다
.
아버지 수업
{
protected $salutation = "안녕하세요!" //인사말
공개 함수 getSalutation()
{
print("$this->경례n");
$this->식별();
}
보호된 함수 식별()
{
print("나는 아버지입니다.n");
}
};
Son 클래스는 Father를 확장합니다.
{
protected $salutation = "Hey!"; //보호된 상위 클래스의 $salutation을 덮어씁니다.
protected functionidentify() //부모 클래스의 protectedidentify()를 덮어씁니다.
{
print("나는 아들입니다.n");
}
};
$obj = 새로운 아들();
$obj->getSalutation(); //출력 안녕하세요!
?>
//참고: getSalutation()은 하위 클래스에서 재정의되지 않지만 실제로는 여전히 getSalutation()이 있습니다. 이 클래스의 $salutation 및 식별()은
//Son 인스턴스의 getSalutation()과 동일합니다. subclass 이 메소드는 동적으로 바인딩되므로 Son 인스턴스의 getSalutation() 메소드를 호출하면
상위
클래스의 멤버 인사말 및 식별()이 아닌 Son 클래스의 멤버 인사말 및 식별()이 호출됩니다.
public 및 protected 멤버와 달리 PHP는 그림 2의 예를 참조하세요. 하위 클래스가 인사말 값을 재정의하더라도 "안녕하세요! 저는 아버지입니다."를 출력합니다. 스크립트는 >salutation이 현재 클래스 Father에 바인딩됩니다. 개인 메서드인 식별()에도 유사한 원칙이 적용
됩니다
.
아버지 수업
{
private $salutation = "안녕하세요!"
공용 함수 getSalutation()
{
print("$this->경례n");
$this->식별();
}
개인 함수 식별()
{
print("나는 아버지입니다.n");
}
}
클래스 아들이 아버지를 확장함
{
private $salutation = "안녕하세요!";
개인 함수 식별()
{
print("나는 아들입니다.n");
}
}
$obj = 새로운 아들();
$obj->getSalutation(); //출력 안녕하세요 아버지입니다!
?>
동적 바인딩의 장점은 상속된 클래스가 상위 클래스의 인터페이스와 기능을 유지하면서 상위 클래스의 동작을 변경할 수 있다는 것입니다. 그림 3의 예를 참조하세요. 동적 바인딩 사용으로 인해 isAuthorized 버전이 호출됩니다. deleteUser는 객체 유형에 따라 결정됩니다. 일반 사용자인 경우 User::isAuthorized를 호출하는 PHP는 FALSE를 반환합니다. AuthorizedUser::isAuthorized를 호출하는 PHP는
// haohappy 참고: use 한 문장으로 명확하게 말하면 객체 유형과 메소드 및 속성을 바인딩하는 것입니다. 상위 클래스와 하위 클래스 모두에 존재하는 메소드를 호출하거나 속성에 액세스할 때 먼저 어떤 객체 유형을 결정합니다. 인스턴스가 속해 있고 해당 클래스의 메소드를 호출합니다. 그리고 속성.
<
?php
.
클래스 사용자 //사용자
{
protected function isAuthorized() //인증된 사용자인지 여부
{
반환(거짓);
}
public function getName() //이름 가져오기
{
return($this->이름);
}
public function deleteUser($username) //사용자 삭제
{
if(!$this->isAuthorized())
{
print("권한이 없습니다.n");
반환(거짓);
}
//사용자 삭제
print("사용자가 삭제되었습니다.n");
}
}
클래스 AuthorizedUser는 사용자 //인증 사용자를 확장합니다.
{
보호된 함수 isAuthorized() //isAuthorized() 덮어쓰기
{
반환(TRUE);
}
}
$user = 새로운 사용자;
$admin = 새로운 AuthorizedUser;
//승인되지 않았습니다.
$user->deleteUser("Zeev");
//인증됨
$admin->deleteUser("지브");
?>
Private 클래스 멤버가 정적 바인딩을 시뮬레이션하는 이유는 무엇입니까? 이 질문에 대답하려면 Private 멤버가 필요한 이유를 기억해야 합니다.
원하지 않는 경우에만 Private 멤버
를 사용하는 것이 합리적입니까?상속할 하위 클래스는 부모 클래스의 동작을 변경하거나 특수화할 때만 사용됩니다. 일반적으로 좋은 개체 계층 구조에서는 대부분의 기능을 하위 클래스로 특수화, 개선 또는 변경할 수 있습니다. 객체 지향 프로그래밍의 기본 사항 하위 클래스가 상위 클래스의 특정 부분을 변경하는 것을 허용하지 않으려는 경우와 같은 특정 상황에서는 전용 메서드나 변수가 필요합니다.