<?php //1. 类的声明(包括构造方法、析构方法)
class PersonA {
var $name; //成员属性,用var声明
public $age; //当有其他修饰的时候,就不要用var了
private $sex;
function eat(){ //成员方法
echo $this->name." eat now<br/>"; //使用this来引用类的成员属性
}
private function run(){ //带有权限修饰的成员方法
echo "run now<br/>";
} function __construct($name, $age = 23) { //构造方法,只能有一个,但可以通过默认参数实现类似于C++中的构造函数重载
$this->name = $name;
echo $name." 你好<br/>";
}
function __destruct() { //析构方法,PHP中已经有垃圾回收机制,析构方法在垃圾回收程序回收对象之前自动调用
echo $this->name." 再见<br/>";
}
} //2. 类的实例化
$person = new PersonA("张三");
$person->eat(); //3. 类的封装
/* private、public修饰符 基础的oop知识,不再赘述
* 主要介绍以下几个魔术方法
* __set(propertyName, propertyValue) 使用户可以直接给private变量赋值,赋值时会调用该方法
* __get(propertyName) 在获得private变量的值时调用
* __isset,__unset 对private变量调用iset和unset时使用
*/
class PersonB{
private $name;
private $sex;
public function __set($proName, $proValue){
if ($proName == "sex") {
if ($proValue != "男" && $proValue != "女") return;
}
echo "set $proName to $proValue <br/>";
$this->$proName = $proValue;
}
public function __get($proName) {
echo "get $proName value {$this->$proName} <br/> ";
return $this->sex;
}
public function __isset($proName) {
return isset($this->$proName);
}
public function __unset($proName) {
unset($this->$proName);
}
} $person = new PersonB();
var_dump(isset($person->sex));
$person->sex = "123";
$person->sex = "男";
var_dump(isset($person->sex));
echo $person->sex."<br/>";
unset($person->sex);
var_dump(isset($person->sex));
echo "<br/><br/>"; //4. 类的继承
/* PHP中采用的是和JAVA一样的单继承,使用extends关键字
* protected修饰的成员可以在子类中访问
* 支持重写,但子类中的方法开放程度要高于父类
* 使用parent::fun()可以调用父类中的方法;
*/
class PersonAson extends PersonA {
function eat() {
parent::eat();
echo "son eat now<br/>";
}
}
$person = new PersonAson("李四");
$person->eat();
unset($person); //也可以显示调用
echo "<br/><br/>"; //5. 常见的关键字和魔术方法
/* 常用关键字
* final final修饰的类不能被继承,final修饰的方法不能被重写,注意final不能用来修饰变量
* static 标志类属性和类方法,为所有类共有,使用(类名::方法名)来访问,在类自身也可以用(self::方法名)来访问
* const 定义类常量,通常变量名都是大写,而且使用时不需要$操作符
* instanceof 确定一个对象是类的实例
* clone 使用clone拷贝一个对象
* 常用魔术方法
* __toString() 获取对象字符串表示,输出对象引用时会调用此方法
* __call() 调用类中不存在的方法会调用该防范,第一个参数为函数名,第二个参数为函数列表.有独特的作用.
* __autoload() 在用一个该文件中没有的类的时候,会自动调用该方法,可以在该方法中include类文件等操作
* serialize 对象串行化,以在网络中传输或者保存在文件中.
* unserialize 对象反串行化
*/
$person = new PersonA("王五");
$personclone = clone $person;
$personclone->eat();
var_dump($personclone instanceof PersonA);
unset($person);
unset($personclone);
echo "<br/>"; class PersonC {
private $name;
private $age;
public function __construct($name, $age) {
$this->name = $name;
$this->age = $age;
}
public function __toString() {
return "name: ".$this->name." age: ".$this->age."<br/>";
}
public function __call($method, $args) { //连贯操作,这里来给变量赋值,在SQL中可能会常用
if ($method == "name")
$this->name = $args[0];
else if ($method == "age")
$this->age = $args[0]; return $this;
}
}
$person = new PersonC("zhangsan", 15);
echo $person; //这时候其实会调用toString方法
echo $person->name("lisi")->age(20); //巧妙使用__call方法 $person_string = serialize($person);
echo $person_string."<br/>"; $person = unserialize($person_string);
echo $person;
echo "<br/>"; //6. 抽象类与接口
/* abstract class 修饰抽象类,不能被实例化,里面的成员不能是private的.里面可以有抽象方法,用abstract修饰,没有任何实现.
* 子类必须实现所有父类的抽象方法才能实例化,否则也是抽象类.
* interface 所有方法都是抽象方法,只能有const常量,所有成员都必须是public的,子类使用implements实现接口.
* 接口可以实现多个
* 写法和JAVA基本一致,不再赘述.
*/ //7. 简单多态的应用,一个简单的USB接口程序
interface USB {
function run();
}
class UKey implements USB {
public function run() {
echo "Ukey run<br/>";
}
}
class UMouse implements USB {
public function run() {
echo "UMouse run<br/>";
}
}
class Computer {
function useUSB($usb) {
$usb->run();
}
}
$com = new Computer();
$com->useUSB(new UKey());
$com->useUSB(new UMouse());
?>
执行结果
张三 你好
张三 eat now
张三 再见
bool(false) set sex to 男
bool(true) get sex value 男
男
bool(false) 李四 你好
李四 eat now
son eat now
李四 再见 王五 你好
王五 eat now
bool(true) 王五 再见
王五 再见 name: zhangsan age: 15
name: lisi age: 20
O:7:"PersonC":2:{s:13:"PersonCname";s:4:"lisi";s:12:"PersonCage";i:20;}
name: lisi age: 20 Ukey run
UMouse run