If you are using a child-class. Remember to call the constructor of the parent class aswell before you start using it. Otherwise you might get different results then you expected. It is stated in this document, but I got confused by the given example. So, here is my example:
<?php
error_reporting(E_ALL);
class test {
var $var;
function test() {
$this->var = 3;
}
}
class testing extends test {
function testing() {
parent::test();
}
function My_test() {
return $this->var;
}
}
$p = new testing();
echo $p->My_test();
// Returns 3
extends
때때로 기존의 클래스와 비슷한 변수와 함수를 갖는 클래스가 필요할때 가 있다. 실제로, 모든 프로젝트에서 사용할수 있는 범용의 클래스를 선언하고, 특정 프로젝트에서 이런 클래스를 필요에 의해 변경하는 것은 좋은 습관이다. 이런 일을 수월하게 하기 위해서 클래스는 다른 클래스에서 확장(extension) 될수 있다. 이렇게 확장되거나 파생된 클래스는 원래 클래스의 모든 변수와 함수를 소유하고 (이런 경우를 아무도 죽지 않았음 에도 불구하고 '상속'이라고 부른다) 필요로 하는 확장된 선언을 추가할수 있다. 기존 클래스에서 기존 함수나 변수의 선언을 해제하여 뺄수는 없다. 확장 클래스는 항상 하나의 기존 클래스에만 연관되어있다. 즉 다중 상속은 지원되지 않는다. 클래스는 'extends'라는 키워드를 사용하여 확장된다.
<?php
class Named_Cart extends Cart {
var $owner;
function set_owner ($name) {
$this->owner = $name;
}
}
?>
위 코드는 Cart의 모든 변수와 함수는 물론 추가된 변수 $owner 와 추가된 함수 set_owner()를 갖는 클래스를 선언한다. 이로써 이름이 있는 카트를 만들고 카트의 소유자를 설정하고 얻어올수 있다. 이름이 있는 카트에서는 물론 기존의 일반 카트 함수 도 쓸수 있다:
<?php
$ncart = new Named_Cart; // 이름이 있는 카트 만들기
$ncart->set_owner("kris"); // 그 카트에 소유자를 설정
print $ncart->owner; // 소유자 이름을 출력
$ncart->add_item("10", 1); // (기존 cart에서 상속한 함수 사용)
?>
이런 경우를 "부모-자식" 관계라고 부르기도 한다. 부모 클래스를 만들고, 부모 클래스에 기반한 새 클래스를 만들려면 extends를 사용한다: 자식 클래스. 심지어 이런 새로운 자식 클래스를 사용하거나 이 자식 클래스에 기반한 다른 클래스도 만들수 있다.
Note: 클래스는 그것이 사용되기 전에 이미 선언되어 있어야 한다! Cart클래스를 상속하는 Named_Cart클래스가 필요하면 우선 Cart클래스를 먼저 선언해야 할것이다. Named_Cart클래스에 기반한 다른 클래스 Yellow_named_cart 를 생성하고자 한다면 Named_Cart클래스를 먼저 선언해야 한다. 짧게 말해서: 클래스가 선언되는 순서는 중요하다.
extends
03-Mar-2006 10:54
27-Nov-2005 01:48
Just a note: It is possible to have a class inherit from multiple other classes, but only in a one-at-a-time linear hierarchy.
So this works, and C gets A and B functions:
<?php
class A {
public function af() { print 'a';}
public function bark() {print ' arf!';}
}
class B extends A {
public function bf() { print 'b';}
}
class C extends B {
public function cf() { print 'c';}
public function bark() {print ' ahem...'; parent::bark();}
}
$c = new C;
$c->af(); $c->bf(); $c->cf();
print "<br />";
$c->bark();
/**results:**/
//abc
//ahem... arf!
?>
This does NOT work:
<?php
class A {
public function af() { print 'a';}
public function bark() {print ' arf!';}
}
class B {
public function bf() { print 'b';}
}
class C extends B, A /*illegal*/ {
public function cf() { print 'c';}
public function bark() {print ' ahem...'; parent::bark();}
}
$c = new C;
$c->af(); $c->bf(); $c->cf();
print "<br />";
$c->bark();
//Parse Error
?>
19-Nov-2005 05:43
Here is a simple idea that I use when I need my abstract classes (the inherited classes) implemented before my functional classes.
<?php
$_CLASSES = array_merge (
glob ("classes/*/*.abstract.php"),
glob ("classes/*/*.class.php")
);
foreach ($_CLASSES AS $_CLASS) {
require ($_CLASS);
}
?>
31-Mar-2005 06:11
When declaring a class that relies upon another file ( because it extends the class defined in that file ), you should ALWAYS require_once() that file at the top.
This applies even when planning on looping through and including everything in the folder. Use require_once() in your loop, and at the top of the file that NEEDS the include.
07-Mar-2005 01:19
This may seem obvious, but check this scenario. You have a class folder:
+ class
--classA.php
--classB.php
--classC.php
--mainClass.php
Here... classA, classB, classC all extend the mainClass.
If you try to create a function that automatically includes all of the classes in a folder, normally, they are included alphabetically.
When you try to instantiate classC, for example, you will get an error:
"Cannot inherit from undefined class mainClass"
EVEN IF you instantiate the mainClass before you instantiate all of the other classes.
In other words, make sure your primary class is included before all others.
19-Nov-2004 02:48
Multiple inheritence is often more trouble than it's worth. For example, you have a class foo that inherits from both class bar and class baz. Classes bar and baz both have a fubar() method. When you create a foo object and call its fubar() method, which fubar() method is called: bar's or baz's?
It seems to me that using aggregate to glue one class's methods and data to another object is a bit like Ruby's fixins, but I could be wrong...
[[Editor's note:
The aggregate_* functions have been dropped, as of PHP 5
-S
]]
03-Mar-2004 01:35
It is possible to override a method innherited from a parent class by simply re-defining the method (for those of us who enjoy using abstract classes).
<?php
class A
{
var $foo;
function A()
{
$this->foo = "asdf";
}
function bar()
{
echo $this->foo." : Running in A";
}
}
class B extends A
{
function bar()
{
echo $this->foo." : Running in B";
}
}
$myClass = new B;
$myClass->bar();
?>
04-Jul-2003 03:49
Just a simple example about inheritance:
<?php
class a1{
var $a=10;
function a1($a){
$this->a=$a;
}
}
class a2 extends a1{
var $x=11;
function a2($x,$y){
$this->x=$x;
parent::a1($y); // or a1::a1($y) or $this->a1($y)
}
}
class a3 extends a2{
var $q=999;
}
$x=new a3(99,9);
echo $x->a,"<br>",$x->x,"<br> ",$x->q;
?>
The output will be:
9
99
999
23-Jun-2003 03:58
Just a quick note to make things more clear : while multiple inheritance is not allowed, several levels of single inheritance ARE ALLOWED indeed. Just test this example :
<?php
class A {
var $name='A';
function disp() {
echo $this->name;
}
}
class B extends A {
var $name='B';
}
class C extends B {
var $name='C';
}
$truc = new C() ;
$truc->disp(); // Will output C
?>
This is especially important to keep in mind while building a huge object hierarchy. for example :
+GenericObject
->+ Person
->->Employee
->+Computer
->->+WorkStation
->->-> PPC
->->-> Intel
->->+Server
->->->LDAPServer
->->->IntranetWebServer
.. and so on. Multiple level hierarchy relationship are possible in a tree-like structure (each child has one and only one parent, except for the root object).
10-Jun-2003 08:07
a nice example using extends and multiple classes and constructors.
<?php
class CoreObject {
var $name;
function CoreObject($name){
$this->_constructor($name);
}
function _constructor($name){
$this->name = $name;
}
function show(){
printf("%s::%s\n", $this->get_class(), $this->name);
}
function get_class(){
return get_class($this);
}
}
class Container extends CoreObject{
var $members;
function Container($name){
$this->_constructor($name);
}
function &add(&$ref){
$this->members[] = $ref;
return ($ref);
}
function show(){
parent::show();
foreach($this->members as $item){
$item->show();
}
}
function apply(){
}
}
class Person extends CoreObject{
function Person($name){
$this->_constructor($name);
}
}
class Family extends Container {
var $members;
function Family($name){
$this->_constructor($name);
}
}
echo "<pre>\n";
$family = new Family('my family');
$family->add(new Person('father'));
$family->add(new Person('mother'));
$family->add(new Person('girl'));
$family->add(new Person('boy'));
$family->show();
print_r($family);
?>
27-Sep-2002 08:36
[Editor's note: For an alternative to multiple inheritance, see the dynamic binding via object aggregation in the corresponding section of the manual.]
Multiple Inheritance is not supported but it is easy to emulate it:
<?php
class multipleInheritance
{
function callClass($class_to_call)
{
return new $class_to_call();
}
}
class A
{
function insideA()
{
echo "I'm inside A!<br />";
}
}
class B
{
function insideB()
{
echo "I'm inside B!<br />";
}
}
class C extends multipleInheritance
{
function insideC()
{
$a = parent::callClass('A');
$a->insideA();
$b = parent::callClass('B');
$b->insideB();
}
}
$c = new C();
$c->insideC();
?>
---
This will succesfully echo:
I'm inside A!
I'm inside B!
16-Aug-2002 05:37
This prints out 'ab'. No need to create a new instance of a, therefor both methods still exists with same name.
<?php
class a {
function samename(){
echo 'a';
}
}
class b extends a{
function samename(){
echo 'b';
}
function b(){
a::samename();
b::samename();
}
}
$test_obj = new b();
?>
18-Jul-2002 11:42
Just to clarify something about inheritance. The following code :
<?php
class a
{
function call()
{
$this->toto();
}
function toto()
{
echo('Toto of A');
}
}
class b extends a
{
function toto()
{
echo('Toto of B');
}
}
$b=new b;
$b->call();
?>
...will correctly display "toto of B" (that is, the function declared in the parent is correctly calling the redefined function in the child)
11-Dec-2001 07:31
if the class B that extends class A does not have a constuctor function (i.e. a function named B), then the constructor function of A will be used instead, you don't need to make a constructor in B just to call the constructor of A.
For example:
<?php
class A
{
function A()
{
echo "HEY! I'm A!\n";
}
}
class B extends A
{
}
$b = new B();
?>
produces the output:
HEY! I'm A!
07-Nov-2001 08:08
Just one thing that may seem obvious but not mentionned in this page is that you need to include/require the file containing the parent class or else you'll get an error:
<?php
require(dirname(__FILE__).'/'.'myParent.php');
// ...
myChild extends myParent {
// ...
}
// ...
?>
