2010-08-20 3 views
6

그래서, 이것은 내가 계속 진행 한 마지막 잔소리 상속 질문입니다. 그래서 저는 계속해서 묻고 싶습니다. 그래서 PHP에서 예를주지 : 충분히 간단한후드 아래의 상속

<?php 

class Base 
{ 
    private $z = 4; 


    function GetPrivate() 
    { 
     echo $this->z; 
    } 

} 

class Derived extends Base 
{ 
} 

$b = new Base(); 
$d = new Derived(); 

$d->GetPrivate(); 

>

합니다. 언제나 상속에 대해 읽었을 때, 설명은 단지 "당신이 일반 대중과 보호 된 구성원을 물려받은 것"이었습니다. 내가 이해하지 못하는 것은이 예에서 통역사가 어떻게 무엇에 속해 있는지를 보여주는 방법에 관한 몇 가지 사실입니다.

예를 들어 파생 클래스를 만들 때 기본 함수의 "GetPrivate"공용 함수를 사용하여 기본 클래스의 전용 변수를 가져올 수 있습니다. 그러나 상속에 대한 간단한 정의가이 문제와 관련이 없습니다. 내 말은, GetPrivate 메서드를 상속 받았지만 기본 클래스에 속한 메서드의 private 변수에 대한 링크가 여전히 있습니다 ($ this가 파생 클래스 개체를 참조 함에도 불구하고). 개인 변수에 액세스하기 위해 파생 클래스에서 새 함수를 만들 수 없습니다.

따라서 인터프리터는 기본 클래스의 상속 된 함수와 해당 기본 클래스에서만 사용할 수있는 전용 멤버에 대해 유지할 수있는 링크를 파악합니다.

답변

2

인터프리터 (또는 다른 OOP 언어의 컴파일러)는 한 번에 한 단계 씩 액세스를 확인합니다. 이 메인 인과 GetPrivate() 공개 방법이다 (난 당신이 Drerived 또는 Base에 관련 클래스에없는 가정으로 공공 컨텍스트를)

당신이 $d->GetPrivate(); 전화

는 인터프리터는 상황을 확인합니다. 따라서이 문맥에서는 $d->GetPrivate();이 허용되므로 오류가 발생하지 않습니다. GetPrivate()에서

는 콘텍스트 Base$d 같은 목적 및 z에 대한 액세스는 현재 오브젝트 ($d)의 전용 소자이다. 따라서 액세스가 유효합니다.

여기에 나오는 개념은 '데이터 숨김'(액세스 제어)과 '캡슐화'(데이터와 기능의 조합)입니다.

Base 인 상속은 Derived의 개체에 속한대로 사용할 수 있습니다.

여전히 개인 데이터에 대한 링크가 있지만 해당 링크는 직접적인 링크가 아닙니다. 중요성은 Base 클래스 허용으로 액세스가 발생한다는 것입니다. 그래서 귀하의 질문에 대답하는

은 다음과 같습니다

YES! 인터프리터는 기본 클래스의 상속 된 함수와 해당 기본 클래스에서만 사용할 수있는 전용 멤버에 대해 유지할 수있는 링크를 파악합니다.

희망이 도움이됩니다.

2

대답은 간단한 예,이 밖으로 시도 :

<?php 


class Base 
{ 
    private $z = 10; 

    public function getPrivate() 
    { 
     return $this->z; 
    } 
} 


class Derived extends Base 
{ 
    public function getPrivate() 
    { 
     return $this->z; 
    } 
} 

$a = new Derived(); 

echo $a->getPrivate(); 

당신은 그것의 개인 이후 Base 우리가 수있는 Derived 클래스가 더 이상 액세스 z에 지금 우리가 getPrivate 정의했다고이 표시됩니다, 경우 우리는 파생 된 클래스에서 액세스 할 수 있기를 원합니다. 우리는 프라이빗이 아닌 보호되도록 선언해야합니다.

1

글쎄, 나는 파서 세부 사항에 대해 많이 알 수는 없지만, 이해의 열쇠는 visibility이 무엇을 의미하는지 이해에 있습니다

클래스 멤버 공개는 어디서나 액세스 할 수 선포했다. protected로 선언 된 멤버는 클래스 자체 및 상속 된 클래스와 부모 클래스에서만 액세스 할 수 있습니다. 비공개로 선언 된 멤버는 멤버를 정의한 클래스에서만 액세스 할 수 있습니다.

Now, the PHP manual also states

: 예를 들어

, 당신이 클래스를 확장 할 때, 서브 클래스가 부모 클래스에서 공공 및 보호 방법을 모두 상속합니다. 클래스가 이러한 메서드를 재정의하지 않으면 원래의 기능을 유지합니다.

당신은 파생 클래스에 var_dump($d)을 할 경우는 포함 볼 수 Base->z :

object(Derived)#2 (1) { 
    ["z":"Base":private]=> 
    int(4) 
} 

그래서이 자료 Z에 대한 참조이지만, 개인 및 개인 수단 회원 가입일이다 멤버를 정의하는 클래스에서만 액세스 할 수 있으므로 Derived에서 액세스 할 수 없습니다.

private 멤버에게 전달하기 위해 Base에서 공용 메서드를 제공하면 부모 메서드를 통한 액세스를 효과적으로 제어 할 수 있습니다. 어쩌면 $z은 확장 클래스 (예 : 데이터베이스 어댑터)에서 읽기 전용이어야하는 항목입니다.

정보 숨기기 및 액세스 제어입니다. Base를 확장하면 $ z를 잃게됩니다. 상속은 입니다.- 관계입니다. Derived 은 - Base이고 $ z는 있지만 그 자체는 부모가 아니지만 $ z를 가지고 있습니다.