• 设计模式(04):接口和抽象类


    接口和抽象类

    区别

    接口是对行为的抽象,其重点关注的是要有该行为。


    抽象类是对一些共性行为的聚合,将多个子类都有的具体行为抽象成一个方法,形成复用。

    public abstract class Bird {
        private String name;
        private BigDecimal weight;
        private String habit;
    }
    
    public interface IFlyable {
        /**
         * a bird that can fly
         */
        void fly();
    }
    
    public class Sparrow extends Bird implements IFlyable {
        @Override
        public void fly() {
            Console.log("Sparrow can fly");
        }
    }
    

    举例来说,这里我们首先定义了一个 Bird 类,但是,我们却无法在其中定义 fly 方法,为什么呢?


    因为并不是所有鸟都会飞的,如果是在 Bird 中定义的话,那么所有实现子类,都拥有这个行为,因此,我们考虑定义接口,来将其行为抽象成一种能力,只要有该能力的类都可以实现该类,这这里,你甚至可以定义飞机来实现 IFlyable。


    而从语法特性来描述的话,有如下区别:

    • 接口不能有属性,而抽象类可以有属性和方法;
    • 接口中方法不能被实现(Java8 后可以有默认实现方法),抽象类中的方法可以有实现,也可以没有;

    使用时机

    从上面的例子中,也可以看出何时使用抽象类,何时使用接口,关键点是行为的是否可继承性。


    此外,在 Java 要实现多继承的时候,也只能使用接口,因为 Java 不支持多继承。

    存在意义

    首先说抽象类。抽象类本质也是一个类,因此类的继承特性最首要的就是解决代码复用的问题。


    通过继承,可以直接复用父类中的方法,并把需要子类来自定义实现的方法定义成 抽象方法,从而实现复用。


    并且因为继承的关系,还可以使用面向对象中的 **多态 **特性,用抽象类的指针指向子类的对象。


    如果说抽象类关注的是代码复用的话,接口更加关注的就是 解耦。通过接口定义来让第三方不要关注具体的实现,如果你要调用或是实现自己的方法的话,关注定义即可。


    深入了解

    通过,对接口和抽象类的了解,现在,我们来看一下,如何在不支持上述语法特性的语言中,实现接口和抽象类呢。

    在这里,因为没有装 py 和 C++ 的环境,因此就用 Java 简单代替一下,所完成的逻辑和方法是 的。


    用抽象类来实现接口的定义:

    /**
     * @author iceWang
     * @date 2020/10/17
     * 用抽象类来模拟接口
     */
    public abstract class AbstractToInterface {
        protected AbstractToInterface(){};
    
        /**
         * 类似于接口中的定义,子类必须要实现
         */
        public abstract void demo();
    }
    


    用普通类来实现抽象类的作用:

    /**
     * @author iceWang
     * @date 2020/10/17
     * 用普通类来模拟抽象类
     */
    public class ClassToAbstractClass {
        protected ClassToAbstractClass() {
        }
    
        /**
         * 类似于抽象类中的抽象方法的定义,因为要保证子类必须重写,因此直接抛出异常
         */
        public void abstractFunction() throws Exception {
            throw new Exception("Error DesignModel");
        }
    
        /**
         * 类似于抽象类中的普通方法的定义,子类不必一定重写
         */
        public void plainFunction() {
            System.out.println("Hello DesignModel");
        }
    }
    


    用普通类来实现接口的定义:

    /**
     * @author iceWang
     * @date 2020/10/17
     * 用普通类来模拟接口
     */
    public class ClassToInterface {
        protected ClassToInterface() {
        }
    
        /**
         * 类似于接口中的定义,因为要保证子类必须实现,因此直接抛出异常
         */
        public void demo() throws Exception {
            throw new Exception("111");
        }
    }
    

    接口的使用

    接口的实现,可以让我们在编程时采用 面向接口编程 的思想,即只关注接口定义即可,不必过多关注具体的实现细节,从而实现两方的解耦。


    而为了支持面向接口编程,需要在开发过程中:

    • 函数的命名不能暴露任何实现细节;
    • 具体的实现细节进行封装,不暴露给调用者;

    公众号截图




    文章在公众号「iceWang」第一手更新,有兴趣的朋友可以关注公众号,第一时间看到笔者分享的各项知识点,谢谢!笔芯!

  • 相关阅读:
    GROUP BY 和 ORDER BY一起使用
    MySQL中表的复制以及大型数据表的备份教程
    常用sql
    MySQL 数据类型(float)的注意事项
    MySQL VARCHAR字段最大长度到底是多少
    设计-Int(4)和Int(11)谁更美
    5.Flask-Migrate
    4.alembic数据迁移工具
    3.Flask-SQLAlchemy
    2.Flask jinjia2模板
  • 原文地址:https://www.cnblogs.com/JRookie/p/13926234.html
Copyright © 2020-2023  润新知