phpclass/객체모델
{PHP5 객체모델}03.Private 멤버
방글24
2005. 10. 11. 12:10
written: Sep 30 2005
last modified: Oct 11 2005
private 멤버
private 멤버는 해당 클래스내에서만 접근할 수 있습니다. 전역영역 및 다른 클래스는 물론이고 해당 클래스를 상속받은 하위클래스에서 조차 접근할 수 없는 가장 제한적인 방법입니다.
private 변수
[code php;gutter:true]
class my_class {
private $private = "my_class::private!\n;
function foo() {
print "my_class::foo() " . $this->private;
}
}
$obj = new my_class;
/**
* Fatal error: Cannot access private property my_class::$private
*/
print $obj->private;
$obj->foo();
[/code]
< private로 지정된 변수의 동작 >
14번행을 실행하면 아래와 같은 에러를 보게 됩니다.
Fatal error: Cannot access private property my_class::$private in xxx.php on line 14
private로 선언된 변수 $private는 전역 영역에서 접근할 수 없다는 것을 보여주는 것입니다. 반면에 16번행을 실행할 때는 별 탈(?)없이 잘 실행되지요. 클래스 my_class에 선언된 메쏘드 foo() 내에서는 같은 클래스에 선언된 private 변수 $private를 접근하는 데 아무런 문제가 없다는 것을 나타냅니다. 따라서 16번행을 실행하면 private 변수 $private의 값인 "my_class::private!\n이 정상적으로 출력됩니다.
다음에는 클래스 my_class를 상속한 하위클래스에서는 어떤 반응을 보이는지 살펴보겠습니다.
[code php;gutter:true]
class my_class2 extends my_class {
private $private = "my_class2::private!\n;
function foo2() {
print "my_class::foo2() " . $this->private;
}
}
$obj2 = new my_class2;
/**
* Fatal error: Cannot access private property my_class2::$private
*/
print $obj2->private;
$obj2->foo2();
[/code]
< 하위클래스에서 private로 지정된 변수의 동작 >
클래스 my_class에서 private로 선언된 $private를 하위클래스 my_class2에서 같은 변수명을 가지고 private로 선언해 보았습니다. 14번행을 실행하면 역시 아래와 같은 에러를 보게 됩니다.
Fatal error: Cannot access private property my_class2::$private in xxx.php on line 14
이전 에러메시지와 비교해 볼 때 달라진 점은 my_class::$private 대신에 my_class2::$private에 접근할 수 없다는 것입니다.. 만약에 하위클래스 my_class2에서 2번행을 삭제한다면 어떻게 될까요. 이 때는 아래와 같이 Notice 에러를 만나게 될 것입니다.
Notice: Undefined property: my_class2::$private in xxx.php on line 14
에러메시지를 보면 클래스 상위클래스인 my_class에 선언된 $private가 하위클래스로 전혀 상속되지 않으므로 객체 $obj2를 통해 접근한 $private는 처음 만나는 새로운 변수로 처리하고 있다는 것을 알 수 있습니다.
16번행 "$obj2->foo2()"를 실행할 때는 역시 문제없이 잘 실행됩니다. 하위클래스 my_class2에 선언된 메쏘드 foo2() 내에서는 같은 클래스에 선언된 private 변수 $private를 접근하는 데 아무런 문제가 없었다는 것을 알 수 있습니다. 따라서 16번행을 실행하면 메쏘드 foo2()를 통해(5번행) 하위클래스 my_class2에서 선언한 private 변수 $private의 값인 "my_class2::private!\n이 정상적으로 출력됩니다.
private 메쏘드
아래의 예제는 private로 선언된 메쏘드가 해당 클래스와 그 하위 클래스에서 어떻게 동작하는가를 알아보기 위해 작성된 것입니다. 각 행을 실행하면서 발생되는 에러메시지에 대하여는 그 행 바로 위에 주석으로 기술하였으니 참조바랍니다.
[code php;gutter:true]
class my_class {
private $private1 = "my_class::private1!\n;
private $private2 = "my_class::private2!\n;
private function my_private1() {
return "my_class::my_private1()!\n;
}
private function my_private2() {
return "my_class::my_private2()!\n;
}
function foo() {
print "my_class::foo() " . $this->my_private1();
print "my_class::foo() " . $this->my_private2();
}
}
$obj = new my_class;
/**
* Fatal error: Call to private method my_class::my_private1()
*/
print $obj->my_private1();
$obj->foo();
class my_class2 extends my_class {
private $private1 = "my_class2::private1!\n;
private function my_private1() {
return "my_class2::my_private1()!\n;
}
function foo2() {
print "my_class::foo2() " . $this->my_private1();
/**
* Fatal error: Call to private method my_class::my_private2()
* from context 'my_class2'
*/
print "my_class::foo2() " . $this->my_private2();
}
}
$obj2 = new my_class2;
/**
* Fatal error: Call to private method my_class2::my_private1()
*/
print $obj2->my_private1();
/**
* Fatal error: Call to private method my_class::my_private2()
*/
print $obj2->my_private2();
$obj2->foo2();
[/code]
< private로 지정된 메쏘드의 동작 >
42번행과 56번행을 실행하면 아래와 같은 에러메시지를 보게 됩니다.
Fatal error: Call to private method my_class::my_private2() ...
에러메시지를 보면 하위클래스 my_class2로 부터 생성된 객체 $obj2를 통해 my_private2()에 접근을 시도하면 이 메쏘드가 my_class2에는 존재하지 않고, 그 상위클래스에 private로 선언된 메쏘드임을 알 수 있습니다.
위의 에러메시지는 아래와 같이 보여주는 것이 PPP 접근제한자의 개념상 더 좋지 않을까 생각됩니다.
Fatal error: Call to undefined method my_class2::my_private2() in xxx.php on line xx
private 변수 항목에서 살펴보았듯이 이는 상위클래스에서 private로 선언되고 그 하위클래스에서는 선언되지 않은 변수를 하위클래스를 통해 접근할 때 아래와 같은 에러메시지를 보여주는 것과 비교하면 이해가 쉬울 것입니다.
Notice: Undefined property: my_class2::$private in xxxxxxxx.php on line 14