美文网首页
2020-08-28

2020-08-28

作者: 悟道范 | 来源:发表于2020-08-28 22:54 被阅读0次

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

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

    禁止重写策略

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

    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

          本文链接:https://www.haomeiwen.com/subject/dzyrsktx.html