重写、重载
override是重写(覆盖)了一个方法,以实现不同的功能。一般是用于子类在继承父类时,重写(重新实现)父类中的方法。
重写(覆盖)的规则: 1、重写方法的参数列表必须完全与被重写的方法的相同,否则不能称其为重写而是重载. 2、重写方法的访问修饰符一定要大于被重写方法的访问修饰符(public>protected>default>private)。 3、重写的方法的返回值必须和被重写的方法的返回一致; 4、重写的方法所抛出的异常必须和被重写方法的所抛出的异常一致,或者是其子类; 5、被重写的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行重写
6、静态方法不能被重写为非静态的方法(会编译出错)。
overload是重载,一般是用于在一个类内实现若干重载的方法,这些方法的名称相同而参数形式不同。
重载的规则: 1、在使用重载时只能通过相同的方法名、不同的参数形式实现。不同的参数类型可以是不同的参数类型,不同的参数个数,不同的参数顺序(参数类型必须不一样); 2、不能通过访问权限、返回类型、抛出的异常进行重载; 3、方法的异常类型和数目不会对重载造成影响;
PHP所提供的"重载"(overloading)是指动态地"创建"类属性和方法。我们是通过魔术方法(magic methods)来实现的。
class A{
public function test(){
echo "11";
}
}
class B extends A{
#重写父类的方法
public function test(){
echo "22";
}
}
class C{
public function __call($name,$args) {
echo $name;
}
public function __callStatic($name, $arguments){}
}多态
多态:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。在运行时,可以通过指向基类的指针,来调用实现派生类中的方法。
abstract class animal{
abstract function fun();
}
class cat extends animal{
function fun(){
echo "cat say miaomiao...";
}
}
class dog extends animal{
function fun(){
echo "dog say wangwang...";
}
}
function work($obj){
if($obj instanceof animal){
$obj -> fun();
}else{
echo "no function";
}
}
work(new dog());
work(new cat());遍历对象
遍历对象可以使用foreach遍历可见属性。或者实现iterator接口
class MyClass
{
public $var1 = 'value 1';
public $var2 = 'value 2';
public $var3 = 'value 3';
protected $protected = 'protected var';
private $private = 'private var';
}
$c = new MyClass();
foreach ($c as $key=>$v) {
echo $key."=>"$v;
}魔术方法
- __construct 初始化调用
- __desturct 对象销毁时调用
- __call 访问一个不存在的方法的时候调用
- __callStatic 访问一个不存在的静态方法调用
- __get() 访问一个不存在的属性调用
- __set() 修改一个不存在的属性调用
- __isset() 使用isset判断一个高属性的时候调用
- __toString() 当一个对象以一个字符串返回时候触发调用
- __invoke()当把一个对象当初函数去调用的时候 触发
final
final 最终的,如果一个类被定位成final 这个类不能被继承。如果一个方法被定义一个final。这个方法不能被覆盖。
final不能修饰属性。
class A{
final public function test(){}
}
Class B extends A{
public function test(){ //error
}
}对象复制、对象比较
对象复制可以通过 clone 关键字来完成
当对象被复制后,PHP 5 会对对象的所有属性执行一个浅复制(shallow copy)。所有的引用属性 仍然会是一个指向原来的变量的引用。
class A{
public $name = "hello";
}
$a = new A();
$b = clone $a;当使用比较运算符(==)比较两个对象变量时,比较的原则是:如果两个对象的属性和属性值 都相等,而且两个对象是同一个类的实例,那么这两个对象变量相等。
而如果使用全等运算符(===),这两个对象变量一定要指向某个类的同一个实例(即同一个对象)
类型约束
函数的参数可以指定必须为对象(在函数原型里面指定类的名字),接口,数组
function Test(A $a){}后期静态绑定
“后期绑定”的意思是说,static:: 不再被解析为定义当前方法所在的类,而是在实际运行时计算的。也可以称之为“静态绑定”,因为它可以用于(但不限于)静态方法的调用
self的限制
使用 self:: 或者 CLASS 对当前类的静态引用,取决于定义当前方法所在的类
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
self::who();
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}//
B::test();//A
#静态绑定语法
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
static::who();
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}//
B::test();//B
## 实现ar model
class Model
{
public static function find()
{
echo static::$name;
}
}
class Product extends Model
{
protected static $name = 'Product';
}
Product::find();对象和引用
PHP 的引用是别名,就是两个不同的变量名字指向相同的内容。在 PHP 5,一个对象变量已经不再保存整个对象的值。只是保存一个标识符来访问真正的对象内容。 当对象作为参数传递,作为结果返回,或者赋值给另外一个变量,另外一个变量跟原来的不是引用的关系,只是他们都保存着同一个标识符的拷贝,这个标识符指向同一个对象的真正内容。
class A {
public $foo = 1;
}
$a = new A;
$b = $a; // $a ,$b都是同一个标识符的拷贝
// ($a) = ($b) = <id>
$b->foo = 2;
echo $a->foo."\n";对象序列化
在会话中存储对象。使用serialize序列化。