态增加的属性
public function __set($name, $value)
{
$this->arr[$name] = $value;
}
public function __get($name)
{
return isset($this->arr[$name]) ? $this->arr[$name] : null;
}
}
(2)禁止创建动态属性。重写set方法,里面什么也不做。
class Dog {
//这里我们重写__set来管理动态增加的属性
public function __set($name, $value)
{
//just do nothing
}
}
方法重写
在子类中重写父类的方法时要,重写的方法的访问控制符不能比父类的方法的访问控制符的级别小。例如:如果父类的访问控制符为public,则子类重写方法的访问修饰符只能为public,如果父类的为protected,则子类的访问修饰控制符可以为protected或public。重写属性也要遵守上面的规则。
属性重写
如果子类有和父类相同的属性,如果属性是public或者protected则会重写父类的属性,如果是private则创建一个同名的新私有属性,同时仍然会继承父类的同名私有属性。
静态属性
- 静态属性不属于某个对象,而是所有对象共享的属性,每个对象都可以访问它。
- 静态属性属于类的范畴,而不是某个对象的独有特性。
- 在类中,使用和访问静态变量的方式是
self::$静态属性
。
- 在类外,使用和访问静态变量的方式是
类名::$静态属性
(要求访问修饰符为public)。
- 当我们用var_dump()输出一个对象的时候,该对象的静态变量不会被输出。
- 就像其它所有的 PHP 静态变量一样,静态属性只能被初始化为文字或常量,不能使用表达式。所以可以把静态属性初始化为整数或数组,但不能初始化为另一个变量或函数返回值,也不能指向一个对象。
静态方法
- 静态方法的访问方式为
类名::静态方法名()
; 同时也可以用对象名->静态方法名()
;和对象名::静态方法名()
,但是后两种不推荐,尽量只用第一种。
- 在类的外部调用静态方法,要求静态方法的访问修饰符必须是public的。
- 在类内部调用静态方法:
self::静态方法
或者 类名::静态方法
通过$this
也可以。只推荐第一种方式。在类的内部访问静态方法,无论是什么修饰符都可以访问静态方法。
- 静态方法中不可以访问非静态属性和非静态方法。
- 普通的成员方法,可以访问静态属性。
静态属性和普通属性的区别:
(1)加上static称静态变量,否则就是普通属性
(2)静态属性是与类相关的,所有对象共享的属性
(3)普通属性属于每个对象个体的属性。
多态
由于PHP变量没有类型限制,所以PHP是天生支持多态的。
类型约束
类型约束支持的类型有 array 、 callable 、 对象类型 、 接口
抽象类
当父类的一些方法不能确定时,可以用abstract关键字来修饰该方法[抽象方法],用abstract来修饰该类[抽象类]。
(1) 如果你希望把某个方法做成 抽象方法 ,则前面写上 abstract
(2) 如果一个类中有抽象方法,那么该类必须声明为抽象类。
(3) 抽象类最主要的作用在于设计,它的目的是让其它的类继承它,并实现其中的抽象方法。如果子类继承了该抽象类,除非继承该抽象类的子类也被声明为抽象类,否则必须实现抽象类中所有的抽象方法,如果不实现就会报错。
(4) 抽象类不能被实例化
(5) 抽象类可以没有abstract方法
(6) 抽象类可以有非抽象方法,成员属性和常量
(7) 抽象方法不能有函数体
基本语法:
abstract class 类名 {
abstract 修饰符 function 函数名(参数列表);
}
普通类如何继承抽象类?
abstract class Superman {
public $name;
public $age;
public function __construct($name, $age) {
$this->name = $name;
$this->age = $age;
}
abstract public function run();
abstract public function fly();
abstract public function attach();
}
class Spiderman extends Superman {
public function run()
{
echo 'Spiderman is running on the net.<br>';
}
public function fly()
{
echo 'Spiderman can hang in the sky through net.<br>';
}
public function attach()
{
echo 'Spider attach.<br>';
}
}
接口
(1) 接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,再根据具体情况把这些方法写出来。
(2)基本语法:
interface 接口名 {
//方法[不含方法体]
}
(3)接口中所有的方法都不能有主体
(4)一个类可以实现多个接口,接口名之间用逗号隔开
class 类名 implements 接口1, 接口2 {
}
(5)接口中可以有属性,但只能是常量,并且是公开可访问的。默认是public,但不能用public显式修饰
(6)接口中的方法都必须是public的,默认就是public
(7)一个接口不能继承其它的类,但是可以继承别的接口,而且一个接口可以继承多个接口
interface 接口名 extends 接口1, 接口2 {
//方法[不含方法体]
}
(8)接口不能被实例化
(9)接口是更加抽象的抽象类,接口里的所有方法都没有方法体。接口体现了程序设计的多态和高内聚低耦合的设计思想。
(10)说明:
接口的命名规范一般是字符 i 开头,然后第二个字符大写,形式如:iXxxx,比如:iUsb
(11)如何使用接口中的常量
接口名::常量名;
如果某个类要实现接口,需要用implements 关键字。并且实现接口里的所有方法,如果该类要实现多个接口,则所有的接口的所有的方法都要实现,只要存在没有实现的接口里的方法就会报错。
示例:
interface Displayable {
function display();
}
class Base {
function operation() {
echo 'operate something.<br>';
}
}
class SubClass extends Base implements Displayable {
function display()
{
echo 'display.<br>';
}
}
$temp = new SubClass();
$temp->display();
final关键字
(1) 作用:
? 因为安全的考虑,类的某个方法不允许子类通过重写来修改。
? 不希望某个类被其它的类继承。
(2) PHP5新增了一个final关键字。如果父类中的方法被声明为final,则子类无法覆盖该方法。如果一个类被声明为final