继承、访问控制符、子类重载父类的方法、子类调用父类的方法

本文介绍了PHP中的继承概念及其应用,展示了如何通过继承创建类的层次结构,提高代码的复用性和可维护性。同时,深入探讨了PHP中的访问控制符(private、protected、public)的使用方式和限制。

继承

继承性也是面向对象程序设计中的重要特性之一,在面向对象领域有着极其重要的角色,它是指建立一个新的派生类,从先前定义的类中继承数据和函数,而且可以重新定或加进新的数据和函数,从而建立了类的层次或等级关系。但在php中只能使用单继承,就是说一个类只能直接从另一个类中继承数据,但是一个类可以有多个子类。

在软件开发中,类的继承性使所建立的软件具有开放性、可扩充性。这是信息组织与分类的行之有效的方法。它简化了对象、类的创作工作量,增加了代码的可重用性。采用继承性,提供了类的规范的等级结构。通过类的继承关系,使公共的特性能够共享,提高了软件的可重用性。

<?php 
header('content-type:text/html;charset=utf-8');
class Person{
    var $name;
    var $sex;
    var $age;
    function __construct($name,$sex="男",$age=1){
        $this->name=$name;
        $this->sex=$sex;
        $this->age=$age;
    }
    function say(){
        echo "我的姓名:".$this->name. " 性别:".$this->sex. ' 年龄:'.$this->age.'<br/>';
    }
}
//注:不能继承私有的成员属性和方法
class Student extends Person{
//继承Person的三个成员属性(name,sex,age)、一个构造函数、一个成员方法(say)。
    var $school;
    function study(){
        echo $this->name.' 正在 '.$this->school.' 学习<br/>';
    }
}
class Teacher extends Student{
//继承Student的四个个成员属性(name,sex,age school)、一个构造函数、两个成员方法(say、study)。
    var $wage;
    function teaching(){
        echo $this->name.' 正在 '.$this->school.' 教学,工资:'.$this->wage;
    }
}
$teacher=new Teacher('张三','男',40);
$teacher->school='edu';
$teacher->wage=3000;
$teacher->say();
$teacher->study();
$teacher->teaching();
//结果如下:
我的姓名:张三 性别:男 年龄:40
张三 正在 edu 学习
张三 正在 edu 教学,工资:3000

访问控制符

同一个类中 private protected public(默认)
类中子类 protected public
所有的外部成员 public

protected

当类中的成员被定为 protected 对于同一个类的所有成员都没有访问限制,但对于该类的外部代码是不改变操作的,对于该类的子类也不能访问 protected 修饰的成员。

<?php
header('content-type:text/html;charset=utf-8');
class Myclass {
    private $var1=100;
    private function printHello(){
        echo 'Hello';
    }
}
class Myclass2 extends Myclass{
    function UserPerson(){
        echo $var1;
        $this->printHello();
    }
}
$myclass=new Myclass();//实例化类
//echo $myclass->var1;//外部是不能访问private修饰的成员属性
//$myclass->printHello();//外部是不能访问private修饰的成员方法
$myclass1=new Myclass2();
$myclass1->UserPerson();//私有成员属性和私有成员方法不能被继承,所以在子类中访问出错。
//结果如下:
Fatal error: Cannot access private property Myclass::$var1 in D:\WWW\test.php on line 16
Fatal error: Call to private method Myclass::printHello() from context '' in D:\WWW\test.php on line 17
Notice: Undefined variable: var1 in D:\WWW\test.php on line 11
Fatal error: Call to private method Myclass::printHello() from context 'Myclass2' in D:\WWW\test.php on line 12

protected

当类中的成员被定义为protected ,对于该类的子类及子类的子类都有访问权限,可以进行属性、方法的读及写操作。当不能被该代码的外部代码访问,该子类的外部代码也不具有访问其属性和方法的权限。

<?php
header('content-type:text/html;charset=utf-8');
class Myclass {
    protected $var1=100;
    protected function printHello(){
        echo 'Hello<br>';
    }
}
class Myclass2 extends Myclass{
    protected $var2=200;
    function UserPerson(){
        echo $this->var1.'<br/>';
        $this->printHello();
    }
}
$myclass1=new Myclass2();
$myclass1->UserPerson();
//echo $myclass1->var1;//被protected 修饰的成员属性和成员方法外部不能访问。
echo $myclass1->var2; //该子类的外部代码也不具有访问其属性和方法的权限

//结果如下:
100
Hello
Fatal error: Cannot access protected property Myclass2::$var1 in D:\WWW\test.php on line 18
Fatal error: Cannot access protected property Myclass2::$var2 in D:\WWW\test.php on line 19

子类重载父类的方法

在php中不能定义重名的函数,也包括不能在一个类中定义重名的方法,所以也就没有办法重载。但是在子类中可以定义和父类同名的方法,因为父类的方法已近存在了,这样在子类中就可以把从父类中继承过来重写。

<?php 
header('content-type:text/html;charset=utf-8');
class Person{
    var $name;
    var $sex;
    var $age;
    function __construct($name,$sex="男",$age=1){
        $this->name=$name;
        $this->sex=$sex;
        $this->age=$age;
    }
    function say(){
        echo "我的姓名:".$this->name. " 性别:".$this->sex. ' 年龄:'.$this->age.'<br/>';
    }
}
class Student extends Person{
    var $school;
    function __construct($name,$sex="男",$age=1,$school=''){
        $this->name=$name;
        $this->sex=$sex;
        $this->age=$age;
        $this->school=$school;
    }
    //子类重写父类的方法
    function say(){
        echo "我的姓名:".$this->name. " 性别:".$this->sex. ' 年龄:'.$this->age.' 在'.$this->school.'学校上学<br/>';
    }
}
$student=new Student('张三','男',40,'edu');
$student->say();
//结果如下:
我的姓名:张三 性别:男 年龄:40 在edu学校上学

子类调用父类的方法

调用格式 parent::方法名 列如:parent::__construct();

显然上面的代码有问题,显示非常的繁琐。另外,有些父类中的源代码并不是可见的,所以就不能在重载时复制被覆盖方法中的源代码。在php中,提供了在子类重载的方法中调用父类中被它覆盖的方法功能。这样就可以在子类重写的方法中,继续使用从父类中继承过来的方法,然后添加一些新的功能。

<?php 
header('content-type:text/html;charset=utf-8');
class Person{
    var $name;
    var $sex;
    var $age;
    function __construct($name,$sex="男",$age=1){
        $this->name=$name;
        $this->sex=$sex;
        $this->age=$age;
    }
    function say(){
        echo "我的姓名:".$this->name. " 性别:".$this->sex. ' 年龄:'.$this->age.'<br/>';
    }
}
class Student extends Person{
    var $school;
     function __construct($name,$sex="男",$age=1,$school=''){
        parent::__construct($name,$sex,$age);//调用父类的构造函数
        $this->school=$school;
    }
    //方法重写
    function say(){
        parent::say();//调用父类的say()方法
        echo ' 在'.$this->school.'学校上学<br/>';
    }
}
$student=new Student('张三','男',40,'edu');
$student->say();
//结果如下:
我的姓名:张三 性别:男 年龄:40
在edu学校上学
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值