php基础巩固加强(七)

php面向对象(oop)特性之继承

继承

继承的现实意义:后代拥有父代的财产和能力

程序的继承:面向对象才有的概念,如果某个类与另外一个类基本上功能差不多,然后稍微会多出一点功能。将这个多出功能的类定义为一个子类,然后基本功能的类定义为父类,然后将子类继承父类。

子类的对象能够拥有子类和父类的所有属性(public和protected)以及方法的使用。

继承的关键字:extends

继承语法

class 父类

{

    

}

//继承

class 子类 extends 父类

{


}

属性继承:所有的非静态属性都被继承

方法继承:

1.公有的(public)可以被继承

2.受保护的(protected)可以被继承

3.私有的(private)不能被继承

继承demo如下:

<?php

   //继承
   //父类
   class Father
    {
        //属性
        public $name = '犬夜叉';   //名字
        protected $money = 1000; //财产
        private    $wife = '桔梗';   //老婆

        //方法
        public function cook()
        {
            echo 'Father cook';
        }
        protected function gongfu()
        {
            echo '家族功夫';
        }
        private function steel()
        {
            echo '偷东西';
        }

        protected function getWife()
        {
            echo $this->wife;
            //$this->steel();
            $this->test();
            //var_dump($this);
        }
    }

   //子类继承父类
   class Son extends Father
    {
        //什么都不做

        public function callFather()
        {
            //$this->gongfu();          //可以继承父类受保护的方法
            //$this->steel();           //不能继承父类私有的方法
            $this->getWife();
        }

        public function callFatherProperty()
        {
            echo $this->name;  //可以
            echo $this->money; //可以
            echo $this->wife;  //不可以
        }

        protected function test()
        {
            echo 'test';
        }
    }


   $son = new Son(); //实例化子类
   //var_dump($son);

   //方法继承
   //$son->cook();        //调用成功,继承了父类中的公有方法
   //$son->gongfu();  //调用失败,继承成功,受保护的方法不能在类外部访问(gongfu在son类中没有所以是调用的父类的gongfu函数 但是gongfu是protected修饰,protected修饰的只能在类中访问,类的外部访问不了 所以这里是成功继承了 但是调用失败。)
   //$son->steel();   //调用失败,继承失败,父类中私有的方法不能被继承

   $son->callFather();
   //$son->callFatherProperty();

继承链

1. 凡是使用了extends继承,继承是双向的。只要在继承链上,就可以对链上的其他类的公有和受保护的方法进行访问。

2. 在php中不支持多重继承(一个子类继承自多个父类),使用链式结构实现多重继承

B extends A

C extends B  C既有B类的属性和方法,又有A类的属性和方法。

3. 私有的属性或者方法都必须在对应的类中才能被访问,其他地方都不可以。

4. 如果子类拥有与父类同名的属性或者方法会怎么样?这就是接下来我们要说的重写的概念啦

重写(override)

当子类拥有与父类同名的方法或者属性的时候,会重写父类的属性和方法。(前提是:非私有的才可以被重写

1.如果在子类重写了父类的方法之后,需要父类的同名方法也执行。

2.parent关键字: 代表父类,其实parent代表的父类对象

3.重写要求: 子类的权限要比父类的权限(权限就是访问修饰符[public,protected,private])要开放(或者子类的权限大于等于父类的权限)

重写demo如下:

//重写
class  Father
{
    //属性
    public $name = '康熙';
    protected $money  = 20000;
    private $age = 69;

    //方法
    public function publicFather()
    {
        echo __METHOD__,'<br/>';
    }
    protected function protectedFather()
    {
        echo __METHOD__,'<br/>';
    }
    private function privateFather()
    {
        echo __METHOD__,'<br/>';
    }

    public function call()
    {
        $this->publicFather();
        $this->protectedFather();
        $this->privateFather();
    }
}

//子类
class Son extends Father
{
    //属性
    public $name = '雍正';
    protected $money = 40000;
    private $age = 42;

    //方法
    public function publicFather()
    {
        //Father::publicFather();
        //parent::publicFather();    //调用父类的publicFather()方法  输出:Father::publicFather
        echo __METHOD__,'<br/>';  //输出:Son::publicFather
    }
    protected function protectedFather()
    {
        echo __METHOD__,'<br/>';
    }
    private function privateFather()
    {
        echo __METHOD__,'<br/>';
    }
}

//实例化
$son = new Son();
//var_dump($son);

//调用方法
//$son->call();

//调用子类覆盖父类的方法
$son->publicFather();   //输出:Son::publicFather

特殊类

final类

final: 最终的意思

类:  final修饰的类,表示该类不能被继承。

方法: final修饰的方法,不允许子类重写

final demo如下:

//final类的测试
final class Son
{
    public function __construct()
    {
        echo __METHOD__;
    }
}

/*
class Grade extends Son
{

}

$grade = new Grade(); //报错: 使用final修饰的类 不能被继承*/


//final方法的测试
class test1
{
    final public function method1()
    {
        echo 'hell world';
    }
}

class test2 extends test1
{
    public function method1()
    {
        echo 'test1 hello world';
    }
}

$test2 = new test2();
$test2->method1();    //报错  父类中使用final修饰的方法(method1)不能被子类重写

abstract类

抽象类: 只能被继承的类,不能被实例化

抽象方法: 方法只有名字没有方法体,方法体就是大括号{}  比如:abstract public function eat(); eat();就是抽象方法

继承抽象类的子类必须实现全部的抽象方法。

抽象类demo如下:

abstract class Person
{
    //属性
    public $name;
    public $age;

    public function setAge($name)
    {
        $this->name = $name;
    }
}

//实例化类
$person1 = new Person(); //报错,abstract修饰的类不能被实例化,只能被继承

抽象方法demo:

//抽象类
abstract class Person
{
    //抽象方法
    abstract public function eat();

    //私有方法
    private function test(){}
}

//子类
class Baby extends Person
{
    //实现父类的抽象方法,增加一个方法体,就是增加一个大括号{}
    public function eat()
    {

    }
}

//实例化
$baby = new Baby();

抽象类的意义

1. 只能被继承

2. 子类必须实现父类的抽象方法

3. 在于规范团队协作能力(如果有不同的团队去实现不同的方案,有必要对不同的团队进行一些规范,相同功能该如何命名)


抽象类中可以有普通类中所有的内容。(包括各式访问修饰限定符)

接口

专门用于规范整个项目的设计结构的工具称之为接口

接口语法

语法关键字: interface

   interface 接口名字{}

接口注意事项如下:

1. 接口不能有非静态属性

2. 接口不能有静态属性

3. 接口里的方法不能有方法体[所谓的方法体就是大括号一对儿{}](必须是抽象方法)

4. 接口里的方法必须使用public修饰

5. 接口内容: 常量+公有的抽象方法

接口demo如下:

//接口
//定义一个接口
interface myInterface
{
    //接口内容

    //属性
    //public $name;          //错误,接口不能有属性
    //public static $age;  //错误,静态属性也不能有

    //常量
    const PI = 3.14;      //可以有常量

    //方法
    //public function test(){echo 'hello world';};   //接口里面只能有抽象方法(不需要使用关键字abstract)
    public function test();

    //私有方法
    //private function test1();       //接口里面不能有私有方法

    //受保护的
    //protected function test2();  //接口里面不能有受保护的(protected)方法

    public static function test3();
}

接口的意义

接口是比抽象类还抽象的"类"(与类结构相似)。

接口纯粹用来规范整个项目的结构的。

实现接口

语法: 类 implements(实现) 接口

实现接口demo如下:

//定义一个接口
interface myInterface
{
    public function test();
    
    public static function test3();
}

//实现接口
class Person implements myInterface
{
    //实现接口中所有的抽象方法

    //实现接口的方法的时候,不能对应的权限降低
    public function test()
    {
        echo 'hello world';
    }

    public static function test3()
    {
        echo 'static funciton';
    }
}

多接口实现(一个类实现多个接口称为多接口实现)

一个类可以实现多个接口,称之为多接口实现

实现多接口demo如下:

//实现多接口
interface A
{
    public function testA();
}

interface B
{
    public function testB();
}

//定义一个C类,实现A接口和B接口
class C implements A,B
{
    //必须实现接口里的所有方法
    public function testA()
    {
        echo '实现了接口A里的testA方法';
    }

    public function testB()
    {
        echo '实现了接口B里的testB方法';
    }
}

接口继承接口(接口与接口之间可以使用extends关键字来联合。)

接口继承接口并实现接口demo如下:

//接口继承接口

interface A
{
    public function test();
    public function testA();
}

//接口继承接口
interface B extends A
{
    public function testB();
}


//实现接口
class C implements B
{
    public function test()
    {

    }

    public function testA()
    {

    }

    public function testB()
    {
        
    }
}

一般情况下,小公司不会用这个。大公司或者有多个团队合作的时候需要使用接口来进行项目规范。

问题

1.PHP是否支持多继承?如果不支持,能不能模拟?

答:PHP不支持多继承,可以通过链式继承来模拟一个子类继承多个父类。

2.接口是不是类?

答:接口不是类,类是用关键字class修饰,接口是使用interface(内容结构有点相似)


声明:禁止任何非法用途使用,凡因违规使用而引起的任何法律纠纷,本站概不负责。

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

精彩评论

全部回复12人评论7,777人参与