面向对象
面向对象的三大特性:封装、继承、多态
多态
多态也就是多种形态,分为方法重写和方法重载.但是PHP不允许方法重载
原因有下:
函数的重载需要满足下面两个条件
1、参数的个数不同——而php支持参数缺省,无法用参数个数区别
2、参数的类型不同——而php是弱类型语言,会根据上下文自动做类型转换
方法重写(override)
方法重写:子类重写了父类的同名的方法
有下面三个规则:
子类的方法名必须和父类的方法名一致
子类重写的方法的参数个数可以和父类的不一致,仍然可以执行,但会弹出E_STRICT严格模式的警告
Declaration of Son::show(age) should be compatible with Father::show()
<?php
class Father{
public function show(){
echo 'this is father</br>';
}
}
class Son extends Father{
public function show($name,$age){
echo 'this is Son';
}
}
?>
3.子类重写的方法的访问权限不能比父类的更加严格,也不能变为static
<?php
class Father{
public function show(){
echo 'this is father</br>';
}
}
class Son extends Father{
// 重写为protected,错误
protected function show(){
echo 'this is Son';
}
}
?>
报错提示:
Fatal error: Access level to Son::show() must be public (as in class Father)
成员修饰符
static(静态的)
static的用法与C++一样,修饰的成员是属于类的,而不是属于对象,因此共存族类间,所有族类都可以调用
静态属性
静态属性不能通过一个类已实例化的对象来访问
静态属性在加载类的时候分配空间,所以不需要实例化就可以直接访问
静态成员在内存只有就一份,是属于类的
静态方法
类的静态方法不能访问普通成员,只能访问静态成员。因为静态成员被创建的时候可能还没有任何实例被实例化
由于静态方法不需要通过对象即可调用,static声明的方法没有$this
指针,所以伪变量 $this 在静态方法中不可用。
self
self表示当前的类
self可以防止类名修改导致多处修改的问题,提升程序健壮性
非静态方法被self::调用,自动转成静态方法(因为方法在类存在时就存在了因此可以从代码区调用,而变量未实例化对象之前是没有的,所以不能用self转为静态属性),但会弹出严格模式的警告(Deprecated: Non-static method Son::show() should not be called statically)
,可以使用@错误控制运算符屏蔽掉
<?php
class Father{
}
class Son extends Father{
public function show(){
echo 'this is Son</br>';
}
public static function fun(){
echo 'this is static</br>';
//@屏蔽就不会报错了
@self::show();
}
}
Son::fun();
?>
static静态延时绑定,确定当前对象
可以使用static进行延时绑定,表示使用该成员的对象,而self表示的是self所在的对象
class Person {
public static $type='人类';
public function showPerson() {
//var_dump($this); //object(Student)#1 (0) { }
echo self::$type; //人类
echo static::$type; //学生 【静态延时绑定】
}
}
class Student extends Person {
public static $type='学生';
public function showStu() {
//var_dump($this); //object(Student)#1 (0) { }
echo self::$type; //学生
echo static::$type; //学生 【静态延时绑定】
}
}
//测试
$stu=new Student;
$stu->showPerson();
echo '<hr>';
$stu->showStu();
final
PHP 5 新增了一个 final 关键字
final修饰的类不能被继承
final修饰的方法不能重写
abstract
主要用来修饰方法和类
1、abstruct修饰的方法叫抽象方法,abstruct修饰的类叫抽象类
2、任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。
3、被定义为抽象的方法能声明,不能实现。
4、继承一个抽象类的时候,子类必须定义父类中的所有抽象方法;另外,这些方法的访问控制不能比父类的更严格
interface接口
1、如果一个类中所有的方法全都是抽象方法,那么这个类就可以声明成接口,接口是一个特殊的抽象类
3、接口中的抽象方法只能是public的,默认也是public权限
4、通过implements实现接口。实现类中必须实现接口中定义的所有方法,否则会报一个致命错误。类可以实现多个接口,用逗号来分隔多个接口的名称
5、不能通过final和abstract修饰接口中的抽象方法
//例子来源于PHP中文网
<?php
// 声明一个'iTemplate'接口
interface iTemplate
{
public function setVariable($name, $var);
public function getHtml($template);
}
// 实现接口
class Template implements iTemplate
{
private $vars = array();
public function setVariable($name, $var)
{
$this->vars[$name] = $var;
}
public function getHtml($template)
{
foreach($this->vars as $name => $value) {
$template = str_replace('{' . $name . '}', $value, $template);
}
return $template;
}
}
继承类与实现接口
继承类与实现接口时,要先继承类再实现接口
class extends Father implements interface{}
类常量
类(接口)中可以放属性、方法、常量
类中的常量使用const定义,可以在类外使用::来访问
<?php
class Father{
const cvar = 9;
}
echo Father::cvar;
?>