【《On Java 8》学习之路——接口】知识点整理分享

本文是对《On Java 8》即《Java编程思想》第五版接口知识点汇总整理,仅供学习分享。

接口

接口和抽象类提供了一种将接口与实现分离的更加结构化的方法。

抽象类和方法

  • 通用接口建立了一个基本形式,以此表达所有派生类的共同部分

  • 如果一个类包含一个或多个抽象方法,那么类本身也必须限定为抽象的

  • 如果创建一个继承抽象类的新类并为之创建对象,那么就必须为基类的所有抽象方法提供方法定义。如果不这么做,新类仍然是一个抽象类,编译器会强制我们为新类加上 abstract 关键字。

  • 可以将一个不包含任何抽象方法的类指明为 abstract,来阻止创建类的对象

  • private abstract 被禁止了是有意义的,因为你不可能在任何子类中合法地定义它。事实上,接口只允许 public 方法

  • 创建抽象类和抽象方法是有帮助的,因为它们使得类的抽象性很明确,并能告知用户和编译器使用意图

  • 抽象类同时也是一种有用的重构工具,使用它们使得我们很容易地将沿着继承层级结构上移公共方法。

接口创建

  • 在 Java 8之前我们可以这么说:interface 关键字产生一个完全抽象的类,没有提供任何实现

  • Java 8 允许接口包含默认方法和静态方法

  • 接口与抽象类最明显的区别可能就是使用上的惯用方式。接口的典型使用是代表一个类的类型或一个形容词,如 Runnable 或 Serializable,而抽象类通常是类层次结构的一部分或一件事物的类型,如 String 或 ActionHero。

  • 接口同样可以包含属性,这些属性被隐式指明为 staticfinal

  • 当实现一个接口时,来自接口中的方法必须被定义为 public。否则,它们只有包访问权限,这样在继承时,它们的可访问权限就被降低了,这是 Java 编译器所不允许的。

  • 关键字 default 允许在接口中提供方法实现——在 Java 8 之前被禁止。

  • 默认方法有时也被称为守卫方法虚拟扩展方法。它允许在不破坏已使用接口的代码的情况下,在接口中增加新的方法。

  • Java 通过默认方法具有了某种多继承的特性

  • 结合带有默认方法的接口意味着结合了多个基类中的行为

  • 方法签名包括方法名和参数类型,返回类型不是方法签名的一部分

  • Java 8 允许在接口中添加静态方法。这么做能恰当地把工具功能置于接口中,从而操作接口,或者成为通用的工具

  • 接口的工作方式使得我们不需要显式声明其中的方法为 public,它们自动就是 public

  • 抽象类和接口的区别

特性接口抽象类
组合新类可以组合多个接口只能继承单一抽象类
状态不能包含属性(除了静态属性,不支持对象状态)可以包含属性,非抽象方法可能引用这些属性
默认方法 和 抽象方法不需要在子类中实现默认方法。默认方法可以引用其他接口的方法必须在子类中实现抽象方法
构造器没有构造器可以有构造器
可见性隐式 public可以是 protected 或友元

抽象类仍然是一个类,在创建新类时只能继承它一个。而创建类的过程中可以实现多个接口。

  • 尽可能地抽象。因此,更倾向使用接口而不是抽象类。只有当必要时才使用抽象类
  • 除非必须使用,否则不要用接口和抽象类。

完全解耦

  • 将接口与实现解耦使得接口可以应用于多种不同的实现,因而代码更具可复用性。

  • 接口没有任何实现——也就是说,没有任何与接口相关的存储——因此无法阻止结合的多接口

  • 将所有的接口名称置于 implements 关键字之后且用逗号分隔。

  • 可以有任意多个接口,并可以向上转型为每个接口,因为每个接口都是独立的类型

  • 使用接口的核心原因:

    一、为了能够向上转型为多个基类型(以及由此带来的灵活性)。

    二、:防止客户端程序员创建这个类的对象,确保这仅仅只是一个接口。

  • 如果创建不带任何方法定义或成员变量的基类,就选择接口而不是抽象类。

使用继承扩展接口

  • 通过继承,可以很容易在接口中增加方法声明,还可以在新接口中结合多个接口
  • 通常来说,extends 只能用于单一类,但是在构建接口时可以引用多个基类接口。注意到,接口名之间用逗号分隔。
interface Monster {
    void menace();
}

interface DangerousMonster extends Monster {
    void destroy();
}

interface Lethal {
    void kill();
}

class DragonZilla implements DangerousMonster {
    @Override
    public void menace() {}

    @Override
    public void destroy() {}
}

interface Vampire extends DangerousMonster, Lethal {
    void drinkBlood();
}
  • 当打算组合接口时,在不同的接口中使用相同的方法名通常会造成代码可读性的混乱,尽量避免这种情况。

接口适配

  • 接口的一种常见用法是策略设计模式 : 编写一个方法执行某些操作并接受一个指定的接口作为参数。

  • “只要对象遵循接口,就可以调用方法” ,这使得方法更加灵活,通用,并更具可复用性。

  • 一个接受接口类型的方法提供了一种让任何类都可以与该方法进行适配的方式。

接口字段

  • 因为接口中的字段都自动是 staticfinal 的,所以接口就成为了创建一组常量的方便的工具。

  • 注意 Java 中使用大写字母的风格定义具有初始化值的 static final 变量。且接口中的字段自动是 public

  • 自 Java 5 开始,有了更加强大和灵活的关键字 enum,在接口中定义常量组就显得没什么意义了。

  • 接口中定义的字段不能是“空 final",但是可以用非常量表达式初始化。

  • 因为字段是 static 的,所以它们在类第一次被加载时初始化,这发生在任何字段首次被访问时

  • 字段不是接口的一部分,它们的值被存储在接口的静态存储区域中。

接口嵌套

  • 接口可以嵌套在类或其他接口中

  • 作为一种新添加的方式,接口也可以是 private 的,实现 private 接口是一种可以强制该接口中的方法定义不会添加任何类型信息(即不可以向上转型)的方式。

  • 接口之间也能嵌套。然而,接口中的元素必须是 public 的。嵌套在另一个接口中的接口自动就是 public 的,不能指明为 private

  • 接口是多实现的途径,而生成符合某个接口的对象的典型方式是工厂方法设计模式。通过这种方式可以将接口与实现的代码完全分离,使得可以透明地将某个实现替换为另一个实现

接口小结

  • 很多人都掉进了这个陷阱,只要有可能就创建接口和工厂。这种逻辑看起来像是可能会使用不同的实现,所以总是添加这种抽象性。这变成了一种过早的设计优化。
  • 任何抽象性都应该是由真正的需求驱动的。当有必要时才应该使用接口进行重构,而不是到处添加额外的间接层,从而带来额外的复杂性。
  • 恰当的原则是优先使用类而不是接口。从类开始,如果使用接口的必要性变得很明确,那么就重构。
  • 接口是一个伟大的工具,但它们容易被滥用。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值