2020-08-28

开心的周五,我们却要加班,没事学习还得继续不是,今天在像一件事情,没想通,先学习再说吧

今天知识点:禁止重写,抽象类,抽象方法,接口开发

禁止重写策略

我们在建立一个类的时候,肯定会有一些方法是不可重写,也是代码规范的一种标准,例如:我们在发送消息的时候,父类已经申明了一个函数来发送消息,那么在我们之类继承时就不能再去复写此函数,为了让代码能够简单明了通用性强(单纯个人理解)

class Message {
    const INTEGRAL = 10;
    protected static $message = '恭喜你获得积分';
    protected static $multiple = 3;

    public function getIntegral(){
        return self::INTEGRAL;
    }

    public final function sendMessage(){
        $message_user = self::$message.bcmul($this -> getIntegral(),self::getMultiple());

        return $message_user;
    }

    public static function getMultiple(){
        return self::$multiple;
    }
}

我们会用到关键词final,英文好点的其实可以不难理解,final修饰符翻译过来就是说最终的意思

class NewYear extends Message{
    function specialMessage(){
        return $this -> sendMessage();
    }

    public function sendMessage()
    {
        return 456;
    }

    public function getIntegral()
    {
        return 100;
    }
}

不难看出,我不小心复写了,那么PHP就要告诉你了,这样子不行

Fatal error: Cannot override final method Message::sendMessage() in E:\phpstudy_pro\WWW\www.studay.com\index.php on line 16

抽象类,抽象方法

官方解释走一波:

PHP 5 支持抽象类和抽象方法。定义为抽象的类不能被实例化。任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。

继承一个抽象类的时候,子类必须定义父类中的所有抽象方法;另外,这些方法的[访问控制](https://www.php.net/manual/zh/language.oop5.visibility.php)必须和父类中一样(或者更为宽松)。例如某个抽象方法被声明为受保护的,那么子类中实现的方法就应该声明为受保护的或者公有的,而不能定义为私有的。此外方法的调用方式必须匹配,即类型和所需参数数量必须一致。例如,子类定义了一个可选参数,而父类抽象方法的声明里没有,则两者的声明并无冲突。 这也适用于 PHP 5.4 起的构造函数。在 PHP 5.4 之前的构造函数声明可以不一样的。

个人观点对于抽象的理解:
抽象就是把具体的能干的事情把它单独拉出来,比如说喝矿泉水,你必须要要打开瓶盖,然后再喝水,那么你打开瓶盖这个动作就是你必须要去完成的事情,你不做我就要提醒你必须要要这样去做

下面上代码:
1.我们定义一个抽象方法,我偏不去做,看他会怎么做尼?

abstract class Message {
    const INTEGRAL = 10;
    protected static $message = '恭喜你获得积分';
    protected static $multiple = 3;
    abstract  public function  getContent();

    public function getIntegral(){
        return self::INTEGRAL;
    }

    public final function sendMessage(){
        $message_user =$this -> getContent().self::$message.bcmul($this -> getIntegral(),self::getMultiple());

        return $message_user;
    }

    public static function getMultiple(){
        return self::$multiple;
    }
}

那么就会告诉你


Fatal error: Class Now contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Message::getContent) in E:\phpstudy_pro\WWW\www.studay.com\index.php on line 9

类现在包含1个抽象方法,因此必须声明为抽象方法或实现其余方法

2.那我只能知错就改,按照他的说法去做了

class Now extends  Message{

    function generalMessage(){
       return $this -> sendMessage();
    }

    function getContent()
    {
        // TODO: Implement getContent() method.
        return '欢迎光临!!!';
    }


}



这是当我在普通的场景的时候需要这样来调用:
欢迎光临!!!恭喜你获得积分30

总结:抽象类就可以理解成对一个事务本身的本质的定义,我要做一件事情的时候,我得抽象出这个事务本身的所有的动作你去完成,但是自己本身不去完成,由子类去完成这些动作的

接口

首先我们定义一个接口

interface  InterfaceModel{
    public function open();
    public function close();
}

我们在使用此接口时

include "InterfaceModel.php";

class interfaceUser implements InterfaceModel{


}



Fatal error: Class interfaceUser contains 2 abstract methods and must therefore be declared abstract or implement the remaining methods (InterfaceModel::open, InterfaceModel::close) in E:\phpstudy_pro\WWW\www.studay.com\interfaceUser.php on line 11

他就是在告诉我们,需要去完成,完善接口中的方法

下面我要写的一个逻辑就是,我想喝一瓶农夫山泉和一瓶脉动,那么我们的的动作要完成,打开盖子,盖起来盖子,用一段代码来实现这个动作。


include "InterfaceModel.php";
class DrinkWater implements InterfaceModel{

    public function open($name)
    {
        // TODO: Implement open() method.

        return '打开'.$name.'的盖子';
    }

    public function close($name)
    {
        // TODO: Implement close() method.
        return '盖起'.$name.'的盖子';
    }

}

class DrinkRefresh implements InterfaceModel{
    public function open($name)
    {
        // TODO: Implement open() method.

        return '打开'.$name.'的盖子';
    }

    public function close($name)
    {
        // TODO: Implement close() method.
        return '盖起'.$name.'的盖子';
    }

}

class Drink {

    public static function instance(string $drink){
        switch (strtolower($drink)){
            case 'water':
                return new DrinkWater;
            case 'refresh':
                return  new DrinkRefresh;
        }
    }
}

$obj = Drink::instance('water');

var_dump($obj -> open('农夫山泉'));
var_dump($obj -> close('农夫山泉'));


$obj = Drink::instance('refresh');

var_dump($obj -> open('脉动'));
var_dump($obj -> close('脉动'));


string(27) "打开农夫山泉的盖子" string(27) "盖起农夫山泉的盖子" string(21) "打开脉动的盖子" string(21) "盖起脉动的盖子"

好家伙,我喝饱了,所以接口我们可以规范一些事情来,比如说我们需要封装一个关于缓存的类,那么缓存很多种,redis,mysql,file等等,但是我们要做的操作都是一样,首先拿到数据,然后做缓存处理。这两个动作不管用什么机制,那么你的流程都是一致的,都是需要拿到,并且将数据处理了,就可以使用接口来完成这样的动作。

最后总结:上面的抽象类和接口的例子,看上去是不是类似?我感觉对于PHP编程来说,抽象类可以实现的功能,接口也可以实现。

抽象类的接口的区别,不在于编程实现,而在于程序设计模式的不同。
一般来讲,抽象用于不同的事物,而接口用于事物的行为。
如:水是饮料,功能性饮料等的抽象概念,但是水并不是所有饮料的的行为,喝水才是对于水的一种行为。
我们在对于一个类抽象出来的时候,他可以有那些牌子,那些种类的水,而对于接口来说,就是需要实现的是我要喝水的这个动作,而不是对于水的概念的抽象,那比如果我们在项目开发中就可以衍生出,做某一个模块的时候,需要具备那些属性,具备那些能力,这种场景就是说我们需要抽象出来一个类,但是我们在具体的实施一个动作的时候,就需要接口去实现了,再次细分,这个动作应该干什么,是否需要摇一摇再喝,还是说开盖即可喝掉,所以可以这样说抽象类包含了接口,抽象类好像女娲造人,需要那些器官,但是不告诉你这些器官长什么样子,长什么样子就需要接口去一一的规定了,眼睛俩,手脚等等,真的理解起来有点绕口,但是多想想也还是能理解到一个皮毛的。。。。。。。。。。。。。

晚安,我的世界,努力两年内能够脱单。

你可能感兴趣的:(2020-08-28)