例如:
<?php
class Con
{
function __construct($num)
{
echo "执行构造函数$num";
}
function __destruct()
{
echo "执行析构函数";
}
}
$a=new Con('1');//输出"执行构造函数1"
$b=new Con('2');//输出"执行构造函数2"
//执行结束,最后输出"执行析构函数执行析构函数"
?>
7.类的继承
1.子类访问父类
php不支持多继承,所以一个子类只能继承一个父类。可以使用extends关键字指明类与类之间继承关系。
<?php
class A//定义父类A
{
public $a_str1;
private $a_str2="string2";
protected $a_str3="string3";
public function a_fun()
{
$this->a_str1= "string1";
}
}
class B extends A//定义子类B,继承于父类A
{
public $b_str;
public function b_fun()
{
parent::a_fun();//子类访问父类的方法
echo $this->a_str1;//子类中访问父类的public属性
$this->a_str3="str3";//子类中访问父类的protected属性
}
}
$b=new B;//创建对象$b
$b->a_fun();//调用A类的a_fun()方法
echo $b->a_str1;//输出"string1"
$b->b_fun();//访问B类的方法
?>
另外值得注意的是:
继承是单方向的,子类可以从父类中继承特性,但父类却无法从子类中继承特性。
如果子类中没有自己的构造函数,那么子类在实例化时会自动调用父类的构造函数。如果子类中有自己的构造函数,则执行自己的构造函数。
如果要在子类中调用父类的方法,除了使用“$this->”外,还可以使用parent关键字加范围解析符,如“parent::functionname()”。
建议使用后一种方法,因为前面的方法容易造成子类和父类方法结构不清。而对于父类的属性,在子类中只能使用“$this->”来访问,属性是不区分父类和子类的。
继承可以是多重的,例如,类B继承了类A,类C继承了类B,那么类C也就继承了类B和类B的父类的所有特性
2.重载
方法的重载是指在一个类中可以定义多个拥有相同名称的方法,通过参数个数和类型来区分这些方法,而PHP目前并不支持这一特性。
但可以通过类的继承,在子类中定义和父类中相同名称的方法来实现类似于方法重载的特性
<?php
class A
{
public $attribute="stringA";
function func()
{
echo "父类A";
}
}
class B extends A
{
public $attribute="stringB";
function func()
{
echo "子类B";
}
}
$b=new B;
echo $b->attribute; //输出"stringB"
$b->func(); //输出"子类B"
?>
3.使用final关键字
PHP 5引入了final关键字,在声明类时使用这个关键字,将使这个类不能被继承。例如,定义一个类A:
final class A
{
//….
}
如果类B尝试继承类A,将会提示以下错误:
Fatal error: Class B may not inherit from final class (A)
另外,如果将final关键字用于声明类中的方法,该方法将不能在任何子类中重载。
8.抽象类和接口
1.抽象类
使用关键字abstract来定义。
特点
不能被实例化。
一个抽象类中至少包含一个抽象方法,抽象方法也是由abstract关键字来定义。
抽象方法只提供了方法的声明,不提供方法的具体实现
<?php
//定义抽象类teacher
abstract class teacher
{
var $number="081101";
var $project;
abstract function shownumber();//定义抽象方法shownumber()
abstract function getproject($project);//定义抽象方法getproject()
function showproject()//在抽象类中定义普通方法showproject()
{
echo $this->project;
}
}
//定义子类stu
class stu extends teacher
{
function shownumber()//重载父类中的shownumber()方法
{
echo $this->number;
}
function getproject ($pro)//重载父类中的getproject()方法
{
$this->project= $pro;
}
}
$obj=new stu;//创建对象
$obj->shownumber();//输出"081101"
$obj->getproject("计算机");
$obj->showproject();//输出"计算机"
?>
2.接口
接口可以多重继承,接口继承使用extends关键字。接口类中定义的方法都是抽象方法。在接口中不能使用属性,但可以使用const关键字定义常量。
<?
interface stu
{
const name="tom";
function show();
function getname($name);
}
?>
接口继承用extends关键字,例如:
<?php
interface A
{
const name="";
function show();
}
interface B extends A
{
function getname();
}
?>
接口可以实例化,接口的实例化称为接口的实现。要实现一个接口需要一个子类来实现接口的所有抽象方法。
定义接口的子类使用implements关键字,另外,一个子类还可以实现多个接口,这样实现了多重继承。
<?php
interface Teacher//定义接口Teacher
{
const name="";
function getname($name);
}
interface Stu//定义接口Stu
{
function showname();
}
class Cteacher implements Teacher//定义继承接口Teacher的类Cteacher
{
var $name="";
function getname($name)
{
$this->name=$name;
}
}
class Cstu implements Teacher,Stu//定义继承接口Teacher和Stu的类Cstu
{
var $name="";
function getname($name)
{
$this->name=$name;
}
function showname()
{
echo $this->name;
}
}
$obj=new Cstu;
$obj->getname("王林");
$obj->showname();//输出"王林"
?>9.类的魔术方法 以两个下划线“__”开头的方法称魔术方法。 1. 克隆对象
__clone,可以确切的拷贝行为和一些操作<?php
class Cid
{
public $id=1;
public function __clone()
{
$this->id=$this->id+1;
}
}
$c1=new Cid;
$c2=clone $c1;
echo $c1->id;//输出1
echo $c2->id;//输出2
?>
<?php
class classname
{
var $attribute=1;
function __get($name)
{
if($name=='attribute')
return $this->$name;
}
function __set($name,$value)
{
if($name=='attribute')
$this->$name=$value;
}
}
$a='attribute';
$obj=new classname;//初始化
echo $obj->$a;//输出1
$set=$obj->$a=10;//输出10
echo $set;
?> 4. 字符串转换
由于类创建的对象的数据类型是对象,所以不能用print或echo语句直接输出。如果要输出对象,可以在类中定义一个__toString方法,在方法中返回一个可输出的字符串
<?php
class TestClass
{
public $foo;
public function __construct($foo)
{
$this->foo = $foo;
}
public function __toString()
{
return $this->foo;
}
}
$class = new TestClass('Hello');
echo $class;//输出'Hello'
?>