private 멤버
private 멤버는 해당 클래스내에서만 접근할 수 있습니다. 전역영역 및 다른 클래스는 물론이고 해당 클래스를 상속받은 하위클래스에서 조차 접근할 수 없는 가장 제한적인 방법입니다.
private 변수
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
/** * private로 지정된 변수의 동작 */ class my_class { private $private = "my_class::private"; 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(); |
18번행을 실행하면 아래와 같은 에러를 보게 됩니다.
Fatal error: Cannot access private property my_class::$private in xxx.php on line 18
private로 선언된 변수 $private는 전역 영역에서 접근할 수 없다는 것을 보여주는 것입니다. 반면에 20번행을 실행할 때는 별 탈(?)없이 잘 실행되지요. 클래스 my_class에 선언된 메소드 foo() 내에서는 같은 클래스에 선언된 private 변수 $private를 접근하는 데 아무런 문제가 없다는 것을 나타냅니다. 따라서 20번행을 실행하면 private 변수 $private의 값인 “my_class::private”이 정상적으로 출력됩니다.
다음에는 클래스 my_class를 상속한 하위클래스에서는 어떤 반응을 보이는지 살펴보겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
/** * 하위클래스에서 private로 지정된 변수의 동작 */ class my_class2 extends my_class { private $private = "my_class2::private"; 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(); |
클래스 my_class에서 private로 선언된 $private를 하위클래스 my_class2에서 같은 변수명을 가지고 private로 선언해 보았습니다. 18번행을 실행하면 역시 아래와 같은 에러를 보게 됩니다.
Fatal error: Cannot access private property my_class2::$private in xxx.php on line 18
이전 에러메시지와 비교해 볼 때 달라진 점은 my_class::$private 대신에 my_class2::$private에 접근할 수 없다는 것입니다.. 만약에 하위클래스 my_class2에서 6번행을 삭제한다면 어떻게 될까요. 이 때는 아래와 같이 Notice 에러를 만나게 될 것입니다.
Notice: Undefined property: my_class2::$private in xxx.php on line 18
에러메시지를 보면 클래스 상위클래스인 my_class에 선언된 $private가 하위클래스로 전혀 상속되지 않으므로 객체 $obj2를 통해 접근한 $private는 처음 만나는 새로운 변수로 처리하고 있다는 것을 알 수 있습니다.
20번행 “$obj2->foo2()”를 실행할 때는 역시 문제없이 잘 실행됩니다. 하위클래스 my_class2에 선언된 메소드 foo2() 내에서는 같은 클래스에 선언된 private 변수 $private를 접근하는 데 아무런 문제가 없었다는 것을 알 수 있습니다. 따라서 20번행을 실행하면 메소드 foo2()를 통해 하위클래스 my_class2에서 선언한 private 변수 $private의 값인 “my_class2::private”이 정상적으로 출력됩니다.
private 메소드
아래의 예제는 private로 선언된 메소드가 해당 클래스와 그 하위 클래스에서 어떻게 동작하는가를 알아보기 위해 작성된 것입니다. 각 행을 실행하면서 발생되는 에러메시지에 대하여는 그 행 바로 위에 주석으로 기술하였으니 참조바랍니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
/** * private로 지정된 메소드의 동작 */ class my_class { private $private1 = "my_class::private1"; private $private2 = "my_class::private2"; private function my_private1() { return "my_class::my_private1()"; } private function my_private2() { return "my_class::my_private2()"; } 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"; private function my_private1() { return "my_class2::my_private1()"; } 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(); |
55번행과 60번행을 실행하면 아래와 같은 에러메시지를 보게 됩니다.
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 xx