设为首页 加入收藏

TOP

PHP面向对象特性(二)
2019-08-23 00:31:44 】 浏览:60
Tags:PHP 面向 对象 特性
} $testObj = new Test(); $testObj2 = new Test(); if ($testObj == $testObj2) { echo '相等<br>'; } else { echo '不相等<br>'; } $testObj2->name = 'jack'; if ($testObj == $testObj2) { echo '相等<br>'; } else { echo '不相等<br>'; }

继承

即使父类的某些属性设置为私有的,子类仍然能够继承,但是对子类却是不可见的。当子类对象使用父类的私有属性的时候,会自动触发重载机制,在子类创建一个和父类私有属性同名的属性。此时子类使用的属性并不是父类的私有属性了,而是通过重载创建的和父类私有属性同名的属性罢了。

如果在子类中需要访问其父类的构造方法( 方法的访问修饰符是public/protected)可以使用父类::方法名(或者 parent::方法名)来完成。(推荐使用parent::方法名,并且一般调用父类构造方法都是parent::__construct();)

调用父类的普通方法直接用this->方法名即可。(也可以用父类名::方法名或者 parent::方法名 ,但是不推荐)

继承并不是直接把父类的属性和方法直接拷贝到子类里面来。而是建立了一种关联。原本我以为是直接把父类的属性和方法直接拷贝过来,最后发现只是建立了一种关联。下图证明了不是直接拷贝,当在子类里调用父类的方法时,父类输出自己的属性时输出结果都和初始化不一样了(private属性除外,因为是私有的,子类无法看见,所以子类也无法重写父类的私有属性),如果是直接拷贝的话,那么当调用父类的方法时应该输出100,200,300才对,所以说继承不是直接拷贝。

class A {

    public    $num1 = 100;
    protected $num2 = 200;
    private   $num3 = 300;

    public function show1() {
        echo 'num1 = ' . $this->num1 . '<br>';
    }

    public function show2() {
        echo 'num2 = ' . $this->num2 . '<br>';
    }

    public function show3() {
        echo 'num3 = ' . $this->num3 . '<br>';
    }
}

class B extends A {

    public    $num1 = 1;
    protected $num2 = 2;
    private   $num3 = 3;

    public function show1() {
        echo 'num1 = ' . $this->num1 . '<br>';
        parent::show1();
    }

    public function show2() {
        echo 'num2 = ' . $this->num2 . '<br>';
        parent::show2();
    }

    public function show3() {
        echo 'num3 = ' . $this->num3 . '<br>';
        parent::show3();
    }
}

$bObj = new B();
$bObj->show1();
$bObj->show2();
$bObj->show3();

输出结果:

num1 = 1
num1 = 1
num2 = 2
num2 = 2
num3 = 3
num3 = 300

重载

PHP所提供的"重载"(overloading)是指动态地"创建"类属性和方法。我们是通过魔术方法(magic methods)来实现的。

当调用当前环境下未定义或不可见的类属性或方法时,重载方法会被调用。本节后面将使用"不可访问属性(inaccessible properties)"和"不可访问方法(inaccessible methods)"来称呼这些未定义或不可见的类属性或方法。

属性重载只能在对象中进行。在静态方法中,这些魔术方法将不会被调用。所以这些方法都不能被声明为 static。从 PHP5.3.0 起, 将这些魔术方法定义为 static 会产生一个警告。

所有重载方法都必须被声明为public。

这些魔术方法都参数都不能通过引用传递。

PHP中的"重载"与其它绝大多数面向对象语言不同。传统的"重载"是用于提供多个同名的类方法,但各方法的参数类型和个数不同。

因为PHP处理赋值运算的方式,__set()的返回值将被忽略。类似的,在下面这样的链式赋值中,__get()不会被调用。

$a = $obj->b = 8;

在除 isset() 外的其它语言结构中无法使用重载的属性,这意味着当对一个重载的属性使用 empty() 时,重载魔术方法将不会被调用。

为避开此限制,必须将重载属性赋值到本地变量再使用 empty()。

//在对象中调用一个不可访问方法时,__call() 会被调用。
public mixed __call(string $name , array $arguments)

//用静态方式中调用一个不可访问方法时,__callStatic() 会被调用。
public static mixed __callStatic(string $name , array $arguments)

属性重载

我们曾经提过,当我们访问或给一个不可访问(protected/private)的属性或者不存在的属性赋值时,就会调用相应的系统魔术方法__get($property)__set($property, $value),如果我们不重写这两个方法,当我们给不存在的属性赋值时,系统会自动帮我们创建一个public的属性,我们可以自己重写这两个方法来管理这些这些动态创建的属性。或者直接不让产生动态属性。当我们不重写这两个方法就不可访问属性赋值时,会报致命错误。

示例:

class Obj {

    protected $name = 'itbsl';



}

$obj = new Obj();
$obj->name = "jack"; //此处会报致命错误

var_dump($obj);

错误信息为:

Fatal error: Uncaught Error: Cannot access protected property Obj::$name

当我们重写了__set()方法就没问题了

class Obj {

    protected $str = 'itbsl';

    public function __set($name, $value)
    {
        $this->$name = $value;
    }

}

$obj = new Obj();
$obj->str = "jack";

var_dump($obj);

属性重载可以帮助我们动态管理新的属性也可以禁止动态创建属性。

(1)动态管理

class Dog {

    //定义一个数组,管理我们动态增加的属性和值
    private $arr = [];
    
    //这里我们重写__set来管理动
首页 上一页 1 2 3 4 下一页 尾页 2/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇PHP变量、数据类型、字符串、运算.. 下一篇php 获取URL 各部分参数

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目