생성자란?
생성자(constructor)는 객체가 만들어질 때 자동으로 호출되며 객체를 초기화시키는 것이 주임무입니다. 객체를 초기화한다는 것은 주로 데이터멤버 초기화, 메모리 할당 등을 수행한다는 것을 의미하지요. 이런 일 외에도 프로그래머 필요에 따라 생성자를 실행하는 중에 멤버 함수 또는 외부함수를 호출하여 프로그램을 시작하기 전에 필요한 기능을 수행할 수도 있습니다. 예를 들면 데이터베이스 연동에 필요한 초기작업과 같은 것이 있고, 데이터베이스와 연동되는 세션기능을 하는 클래스가 있다면 앞 페이지에서 데이터베이스에 저장된 데이터를 데이터베이스에서 읽어온 후 데이터멤버를 초기화하는 기능도 할 수 있겠지요. 또한 쿠키 설정을 생성자에서 수행하는 것이 편리할 수도 있습니다. 이와 같이 프로그래머의 아이디어에 따라서는 더 다양한 활용이 가능하리라 봅니다.
PHP3에서의 생성자
PHP3 에서 구현된 생성자는 그 기능이 매우 제한적으로 이루어지고 있습니다. 여러 개의 클래스가 상속관계에 있을 때, 프로그래머가 마지막으로 정의한 생성자만 수행할 수 있으며, 다른 생성자는 수행되지 않습니다. 이는 스크립트 내에 생성자를 위한 공간이 하나만 확보되어 있기 때문입니다.
이런 이유로 PHP 홈페이지의 온라인 매뉴얼에도 생성자를 사용할 때는 아래와 같이 주의하여 사용하도록 하고 있습니다. 아래는 Manual: Chapter 13. Classes and Objects 문서 중 마지막 부분 발췌한 내용입니다.
......
Caution For derived classes, the constructor of the parent class is not automatically called when the derived class's constructor is called.
......
Caution For derived classes, the constructor of the parent class is not automatically called when the derived class's constructor is called.
......
따라서 프로그래머가 각 클래스마다 생성자를 정의하더라도 생성자로는 상속되지 않으며, 단지 일반 멤버함수로 상속됩니다. 생성자라는 것이 본래 목적이 객체가 만들어질 때 자동으로 호출되며 객체를 초기화시키는 것이 주임무로 최상위 클래스(top class)의 생성자로부터 최하위 파생클래스의 생성자까지 순서대로 호출되어야 하는 특별한 멤버함수입니다. 따라서 생성자로 상속된다면 이러한 생성자로서의 기능을 다해야 함에도 불구하고 PHP3에서 객체 생성할 때 마지막으로 정의된 클래스의 생성자만을 호출하고 그 이상의 부모클래스의 생성자는 실행하지 않고 종료합니다.
[code php;gutter:false]
<?php
class test {
//
// 부모클래스의 생성자
//
function test() {
echo("class test:test() 부모클래스 생성자\n");
}
}
class test2 extends test {
//
// 파생클래스의 생성자
//
function test2() {
echo("class test2:test2() 파생클래스 생성자\n");
}
}
$obj = new test2;
?> [/code]
class test {
//
// 부모클래스의 생성자
//
function test() {
echo("class test:test() 부모클래스 생성자\n");
}
}
class test2 extends test {
//
// 파생클래스의 생성자
//
function test2() {
echo("class test2:test2() 파생클래스 생성자\n");
}
}
$obj = new test2;
?> [/code]
위 예제의 실행결과는 아래와 같습니다.
class test2:test2() 파생클래스 생성자
즉, 객체 생성할 때 마지막으로 정의된 클래스의 생성자만을 호출하고 종료합니다.
PHP3에서의 생성자 체인 구현
위에서 살펴본 바와 같이 PHP에서는 마지막으로 정의된 생성자만 객체 생성할 때 호출되기 때문에 만약 부모클래스의 생성자를 연속적으로 실행하려면 파생클래스의 생성자 내부에서 부모클래스의 생성자를 호출하여야 합니다.
이것이 가능한 것은 생성자의 함수명이 각 클래스마다 다르기 때문에 부모클래스에 정의된 생성자는 나중에 정의된 파생클래스의 생성자에 의해 덮어 쓰이게 되는 것이 아니라 일반 멤버함수로 계속 존재하게 됩니다. 따라서 마지막으로 정의된 생성자로부터 부모클래스의 생성자를 멤버함수로 접근할 수 있습니다.
[code php;gutter:false]
class Cart {
var $items; // Items in our shopping cart
function Cart () {
$this->add_item ("10", 1);
}
// Add $num articles of $artnr to the cart
function add_item ($artnr, $num) {
$this->items[$artnr] += $num;
}
// Take $num articles of $artnr out of the cart
function remove_item ($artnr, $num) {
if ($this->items[$artnr] > $num) {
$this->items[$artnr] -= $num;
return true;
} else {
return false;
}
}
}
class Auto_Cart extends Cart {
function Auto_Cart () {
$this->Cart ();
}
} [/code]
var $items; // Items in our shopping cart
function Cart () {
$this->add_item ("10", 1);
}
// Add $num articles of $artnr to the cart
function add_item ($artnr, $num) {
$this->items[$artnr] += $num;
}
// Take $num articles of $artnr out of the cart
function remove_item ($artnr, $num) {
if ($this->items[$artnr] > $num) {
$this->items[$artnr] -= $num;
return true;
} else {
return false;
}
}
}
class Auto_Cart extends Cart {
function Auto_Cart () {
$this->Cart ();
}
} [/code]
get_parent_class 함수를 이용하면 더 개선된 로직을 구성할 수 있습니다.
[code php;gutter:false]
class Auto_Cart extends Cart {
function Auto_Cart () {
$parent = get_parent_class($this);
$this->$parent ();
}
} [/code]
function Auto_Cart () {
$parent = get_parent_class($this);
$this->$parent ();
}
} [/code]
이처럼 C++과 같은 다른 객체지향언어와 같이 최상위 클래스로부터 최하위 클래스까지 순차적으로 생성자를 수행하기 위해서는 모든 파생클래스 생성자 내부에서 부모클래스의 생성자를 호출해 주는 코드를 포함시켜주면 됩니다.
PHP4에서의 생성자
PHP4 에서도 PHP3와 같이 마지막으로 정의된 생성자만 실행된다는 점에서 같습니다. 그러나 마지막 정의되는 위치가 어디냐에 따라 실행결과가 전혀 달라질 수 있으니 주의하셔야 합니다. 이에 대한 자세한 내용을 "클래스사용법"의 "생성자" 부분을 참조바랍니다.
'phpclass > 클래스활용' 카테고리의 다른 글
{객체지향언어로서의 PHP}6.정적 데이터멤버 (0) | 2000.06.12 |
---|---|
{객체지향언어로서의 PHP}5.정적 멤버함수 (0) | 2000.06.12 |
{객체지향언어로서의 PHP}4.소멸자 (0) | 2000.06.12 |
{객체지향언어로서의 PHP}2.함수 재정의 (0) | 2000.06.12 |
{객체지향언어로서의 PHP}1.함수 중복정의 (0) | 2000.06.12 |