• 【Java编程思想】9.接口


    接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法。


    9.1 抽象类和抽象方法

    Java 提供抽象方法机制,这种方法时不完整的,仅有声明,没有方法体。
    包含抽象方法的类叫做抽象类。如果一个类包含一个或多个抽象方法,那么该类必须被限定为是抽象的(否则编译器报错)。

    一个抽象类不完整的时候,试图创建对象时,编译器会出错(为抽象类创建对象是不安全的),编译器会保证抽象类的纯粹性。
    从一个抽象类继承后,如果想创建该导出类的对象,那么必须为基类中所有抽象方法提供方法实现。不这么做,导出类便也是抽象类,编译器会强制使用 abstract 关键字限定导出类。

    抽象类和抽象方法不仅让类的抽象性明确起来,而且抽象类在重构的时候,可以方便的将公共方法沿着继承层级结构向上移动。


    9.2 接口

    • abstract 关键字允许在类中创建一个或多个没有任何定义的方法-->提供了接口部分,但是没有提供任何相应的具体实现(其实抽象类中也可以选择实现个别方法)。
    • interface 关键字比抽象类跟进了一步,其会产生一个完全抽象的类,没有提供任何实现,只允许定义方法名、参数列表和返回类型,没有任何方法体。

    一个接口代表着“所有实现了该特定接口的类看起来都这个样”。所以接口被用来建立类与类之间的协议
    接口中的方法隐式的被视为 public 的。
    接口可包含域,这些域隐式的是 static 和 final 的。
    当使用一个类去实现接口时,使用 implements 关键字,表示”interface 只是其外貌,现在我要声明它是如何工作的


    9.3 完全解耦

    创建一个能够根据所传递的参数对象的不同而具有不同行为的方法,被称为策略设计模式。这类方法包含所要执行的算法中固定不变的部分,而”策略“包含变化的部分。

    此章节还讲解了适配器设计模式,关于设计模式可以查看归档资料中的 Java 设计模式。


    9.4 Java 中的多重继承

    Java 中可以组合多个接口,被称为多重继承
    在导出类中,不强制要求必须有偶一个是抽象的或者是“具体的”基类。继承类只能一次,但是实现接口可以有若干个。实现的多个接口,都可以向上转型为每个接口(因为每个接口都是一个独立类型)。

    使用接口的核心原因:

    • 能够向上转型为多个基类类型(以及由此而带来的灵活性)。
    • 防止客户端程序员创建该类的对象,并确保这仅仅是建立一个接口
      • 创建不带任何方法定义和成员变量的基类,就应该选择接口,而不是抽象类。

    9.5 通过继承来拓展接口

    一个接口可以继承其他多个接口。来实现方法的拓展。

    一般情况下只可以将 extends 用于单一类的继承,但是也用多个基类接口。

    在不同接口中,最好不要使用相同名称的方法,会造成可读性混乱,以及覆盖、实现和重载混杂在一起的结果。


    9.6 适配接口

    关于策略设计模式:需要编写一个执行某些操作的方法,该方法接收一个指定的接口。然后声明:可以使用任何需要的对象来调用方法,只要这个对象遵循指定的接口。

    到这里说句题外话,虽然内容上接口部分比继承少了许多,但是接口的思想以及在设计模式中的应用,是继承思想的发扬光大,后续在研究设计模式的时候要再次加深理解。


    9.7 接口中的域

    放入接口中的任何域都是 static 和 final 的-->接口可以很方便的管理和创建常量组。

    • 接口中定义的域不能使“空 final”的,但是可以被非常量表达式(例如带有运算符的值)初始化。
    • 在接口中的域首次被访问时,就可以在类第一次被加载的时候初始化。
    • 这些域的值被存储在该接口的静态存储区中

    9.8 嵌套接口

    接口可以嵌套在类或者而其它接口中。

    类中嵌套的接口,可以被实现为 private,这样实现可以强制该接口中的方法定义不要添加任何类型信息(换句话讲就是,不允许向上转型)。
    接口中嵌套的接口,作用域接口的各种规则,特别是所有的接口元素都必须是 public 的。
    实现某个接口的时候,并不需要实现嵌套在其内部的任何接口,而且 private 接口不能再定义它之外的类被实现。


    9.9 接口与工厂

    工厂方法设计模式:(纯接口实现的工厂方法)

    interface Service {
        void method1();
        void method2();
    }
    
    interface ServiceFactory {
        Service getService();
    }
    
    class Implementation1 implements Service {
        Implementation1() {} // Package access
        @Override
        public void method1() {print("Implementation1 method1");}
        @Override
        public void method2() {print("Implementation1 method2");}
    }
    
    class Implementation1Factory implements ServiceFactory {
        @Override
        public Service getService() {
            return new Implementation1();
        }
    }
    
    class Implementation2 implements Service {
        Implementation2() {} // Package access
        @Override
        public void method1() {print("Implementation2 method1");}
        @Override
        public void method2() {print("Implementation2 method2");}
    }
    
    class Implementation2Factory implements ServiceFactory {
        @Override
        public Service getService() {
            return new Implementation2();
        }
    }
    
    public class Factories {
        public static void serviceConsumer(ServiceFactory fact) {
            Service s = fact.getService();
            s.method1();
            s.method2();
        }
        public static void main(String[] args) {
            serviceConsumer(new Implementation1Factory());
            // Implementations are completely interchangeable:
            serviceConsumer(new Implementation2Factory());
        }
    } 
    

    输出:

    Implementation1 method1
    Implementation1 method2
    Implementation2 method1
    Implementation2 method2
    
  • 相关阅读:
    gateway dblink transport mssql image datatype to oracle blob datatype
    Sql server 数据库备份、恢复等
    sql full left right inner cross 基础
    真的发现自己已不再年轻
    利用日志备份恢复时,提示 该 LSN 太晚,无法应用到数据库
    系统调用原理(转)
    Linux添加自定义系统调用
    libusb 介绍
    用户空间与内核空间数据交换的方式(4)relayfs
    用户空间与内核空间数据交换的方式(2)procfs
  • 原文地址:https://www.cnblogs.com/chentnt/p/9791897.html
Copyright © 2020-2023  润新知