java接口的演变(jdk8的default、静态方法,jdk9的私有方法、私有静态方法)
目录:
- 接口的定义
- jdk7-9,接口属性的变化
- jdk8,default、public static method的提出解决了什么问题,使用时需要注意什么
- jdk9的补充(引入private method、private static method)
- 新老生常谈:接口和抽象类的对比
- 单继承还是多继承
一、接口的定义:
首先让我们看一下接口的最新定义:What is an Interface,里面提到:
In the Java programming language, an interface is a reference type, similar to a class, that can contain only constants, method signatures, default methods, static methods, and nested types. Method bodies exist only for default methods and static methods. Interfaces cannot be instantiated—they can only be implemented by classes or extended by other interfaces.
再来看一下jdk1.7时的定义(具体原版定义官网已经找不到了,只能通过书籍及博客找到大概的版本):
An interface in Java is similar to a class, but the body of an interface can include only abstract methods and final fields (constants). A class implements an interface by providing code for each method declared by the interface.
我们知道,在Java中,接口不是类,而是对类的一组需求描述,类遵循接口描述的统一格式进行定义。Java不支持多继承,主要是为了避免多继承会让语言本身变得复杂(像C++),效率也会降低。而接口可以提供多继承的大多数好处,同时避免多重继承的复杂性和低效性。
通过对比上面两段定义,可以看出最新的接口多了一些新的属性,接下来主要围绕这些新属性来理解接口的定义。
二、jdk7-jdk9,接口的变化:
然后再来简单看一下java interface的一个演变过程:
Constants (until Java 1.7)
Method signatures (until Java 1.7)
Nested types (until Java 1.7)
Default methods (since 1.8)
Static methods (since 1.8)
Private methods (since 1.9)
Private static methods (since 1.9)
三、default和public static method:
接着我们先从一个8年前的问题开始:如果接口中有个方法的定义是可以确定的(实现该接口的类必须重复实现该方法),如何更优雅的设计这个接口?
文中提到了许多折中的方法:通过接口里的静态类、借助工具类的静态方法等。
但到了jdk8开始,这个问题被解决了:接口引入了default关键字和静态方法(public static method),接口中通过default修饰的方法可以有方法体,实现具体功能。看下面代码:
- public interface Skill{
- void oldSkill();
- default public void newSkill(){
- System.out.print("实现了这个接口的类可以不实现这个方法");
- }
- public static newStaticSkiil(){
- System.out.print("实现了这个接口的类可以不实现这个静态方法");
- }
- }
引入default的目的官网有解释:Default Method ,总的来说,引入default关键字是为了当接口有新的行为且现有依赖该接口的类与接口不需做任何改变,可以不再对于已实现该接口的类或继承该接口的接口进行修改,可以更加方便的拓展现有接口。
文中还指出,对于拓展了包含default method的接口或类:
- Not mention the default method at all, which lets your extended interface inherit the default method.(可以不理,直接继承)
- Redeclare the default method, which makes it
abstract
.(重新声明为抽象方法) - Redefine the default method, which overrides it.(重新定义方法)
最后,还提到了jdk8开始,接口可以支持静态方法(public static method),这些都是为了接口可以有更好的演变性。
例如,jdk8开始引入的Lambda语法以及Stream API,都是在接口层实现的,因此default及public static method的提出算是为新的设计服务,也响应了这么久以来定义接口方法的呼声。
Collection接口中,default关键字的身影:
引入default关键字后,有些地方可能要注意一下。首先是如果类实现的多个接口都包含了对同一个方法的default定义,那这个方法必须重写,看下面例子:
- public interface Ina {
- default void say(){
- System.out.println("say a");
- }
- }
- public interface Inb {
- default void say(){
- System.out.println("say b");
- }
- }
如果classc在实现这两个接口时不重写say方法,那编译器无法确定到classc调用say方法时,选择哪一个接口的方法。因此Classc必须重写say:
- public class classc implements Ina,Inb {
- @Override
- public void say(){
- System.out.println("say c");
- }
- }
当然,根据上面提示的3条规则,我们也可以把say方法重新声明为抽象方法:
- public interface Ind extends Ina{
- public abstract void say();
- }
四、jdk9的补充:
jdk9中,接口引入的私有方法(private method)和私有静态方法(private static method)。由于不可被继承,因此私有方法必须定义方法体才有意义。同时也意味着接口的私有方法和私有静态方法不可被实现该接口的类或继承该接口的接口调用或重写。私有方法(private method)和私有静态方法(private static method)的提出都是对jdk8提出的default和public static method的补充。
默认方法和静态方法可以共享接口中的私有方法,因此避免了代码冗余,这也使代码更加清晰。如果私有方法是静态的,那这个方法就属于这个接口的。并且没有静态的私有方法只能被在接口中的实例调用。
五、接口和抽象类的区别:
抽象类定义:An abstract class is a class that is declared abstract—it may or may not include abstract methods. Abstract classes cannot be instantiated, but they can be subclassed.
jdk8之后,接口的行为不再局限在“描述”,接口的行为具有了“定义”,对后期接口的演变和拓展提供了便利性,也表示类的行为可以多继承了;当然即使是多了这些新特性,接口还是和抽象类有一条最明显的分界线:接口无状态,抽象类只能单继承。接口的成员域依然只能是常量,接口依然不能实例化。除此之外,还有权限上的区别,不支持protect声明及包可见等属性。
六、单继承还是多继承:
不过,接口的这些新属性是为了更好的服务“单继承多实现”的理念还是更好的往“多继承”靠拢呢?网上有很多不同的声音,而本人更倾向于更好的服务“单继承多实现”,我们知道,最大的改变还是jdk8提出的default和public static method,接口跳出了只能“声明”方法,只有public abstract method的界限,从而使得原有框架上多出了更多优雅的设计。打破的规则如果可以让Java更优雅,那这规则就是应该被打破的。
参考:
《Java核心技术 卷1》
https://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html
https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
https://en.wikipedia.org/wiki/Interface_(Java)
More Power to Interface in Java 9
Java Interface-Implementation Pair(8年前的问题)
java接口的演变(jdk8的default、静态方法,jdk9的私有方法、私有静态方法)的更多相关文章
- 无所不能的PowerMock,mock私有方法,静态方法,测试私有方法,final类
1.为什么要用mock 我的一本书的解释: (1)创建所需的DB数据可能需要很长时间,如:调用别的接口,模拟很多数据 (2)调用第三方API接口,测试很慢, (3)编写满足所有外部依赖的测试可能很复杂 ...
- Python进阶----类的结构(公有成员 , 私有成员(私有属性,私有方法),类方法,静态方法,属性) ,isinstance 和issubcalss ,元类(type())
Python进阶----类的结构(公有成员 , 私有成员(私有属性,私有方法),类方法,静态方法,属性) ,isinstance 和issubcalss ,元类(type()) 一丶类的结构细分 ...
- 可能是把 Java 接口讲得最通俗的一篇文章
读者春夏秋冬在抽象类的那篇文章中留言,"二哥,面试官最喜欢问的一个问题就是,'兄弟,说说抽象类和接口之间的区别?',啥时候讲讲接口呗!" 对于面向对象编程来说,抽象是一个极具魅力的 ...
- Java 接口和抽象类差别
原文:http://blog.csdn.net/sunboard/article/details/3831823 1.概述 一个软件设计的好坏,我想非常大程度上取决于它的总体架构,而这个总体架构事实上 ...
- 使用PowerMockito和Mockito进行模拟测试,包括静态方法测试,私有方法测试等,以及方法执行的坑或者模拟不成功解决
依赖:这个很重要,不同版本用法也有点区别: <dependency> <groupId>org.mockito</groupId> <artifactId&g ...
- JavaScript【面向对象】-静态方法-私有方法-公有方法-特权方法
JavaScript面向对象是近年来比较火的一个概念了,由于小弟才疏学浅,虽然做过不少的web项目,看了网上很多深奥的资料和教程,还是对他们深奥 的理论一知半解,前段时间看了点书,总算有了自己的理解, ...
- JDK8新增接口的默认方法与静态方法
JDK8之前,interface中可以定义常量和抽象方法,访问修饰符是public. public interface A { /** a1和a2写法是等价的 */ public static fin ...
- JDK8新特性之接口默认方法与静态方法
接口默认方法与静态方法 有这样一些场景,如果一个接口要添加一个方法,那所有的接口实现类都要去实现,而某些实现类根本就不需要实现这个方法也要写一个空实现,所以接口默认方法就是为了解决这个问题. 接口静态 ...
- JDK8.0接口中的默认方法和静态方法
我们在接口中通常定义的方法是抽象方法,即没有方法体,只有返回值类型和方法名:(public abstract) void Method(); 类在实现接口的时候必须重写抽象方法才可以 jdk8中新加的 ...
随机推荐
- 微信小程序集成腾讯云 IM SDK
微信小程序集成腾讯云 IM SDK 1.背景 因业务功能需求需要接入IM(即时聊天)功能,一开始想到的是使用 WebSocket 来实现这个功能,然天意捉弄(哈哈)服务器版本太低不支持 wx 协议(也 ...
- Java 并发编程(二):如何保证共享变量的原子性?
线程安全性是我们在进行 Java 并发编程的时候必须要先考虑清楚的一个问题.这个类在单线程环境下是没有问题的,那么我们就能确保它在多线程并发的情况下表现出正确的行为吗? 我这个人,在没有副业之前,一心 ...
- valueForKey与valueForKeyPath 区别
1.删除数组中重复的数据 2.valueForKeyPath:可以深层次取到子属性,不管隐藏的多深 valueForKey:无法取到深层次子属性 但是也有其相似的地方: 比如:快速找到字典数组中ke ...
- 关于ArrayList源码
一.构造方法 private static final int DEFAULT_CAPACITY = 10; //空参的构造方法,初始化数组长度为默认值,默认值为10 public ArrayList ...
- 松软科技课堂:Winform之TextBox
松软科技文(www.sysoft.net.cn): 文本框的几种模式:Multiline(多行).PasswordChar(密码)将文本框的PasswordChar设为*就是密码框效果,将MultiL ...
- u盘重装ubuntu16.04过程遇到的问题
该博文主要记录ubuntu16.04重装过程中分区问题 1. /swap交换区,Logical(逻辑分区),swap area; 一般为物理内存的2倍; 例如你电脑的运行内存是4G, 则/swap可以 ...
- 数据库占用CPU过高,性能分析与调优
一.使用 dstat -tcdlmnsygr --disk-util 查看当前系统资源使用状况,当前cpu使用率100% 二.使用TOP命令 查看当前占用CPU进程,可以看到当前占用CPU进程最高的是 ...
- 公用的update
包结构: ===================================== jdbc.properties路径:/jdbc-1/src/jdbc.properties 内容: #连接MySQ ...
- 当 K8s 集群达到万级规模,阿里巴巴如何解决系统各组件性能问题?
作者 | 阿里云容器平台高级技术专家 曾凡松(逐灵) 本文主要介绍阿里巴巴在大规模生产环境中落地 Kubernetes 的过程中,在集群规模上遇到的典型问题以及对应的解决方案,内容包含对 etcd.k ...
- [转载 ]五种常见的 PHP 设计模式
五种常见的 PHP 设计模式 策略模式 策略模式是对象的行为模式,用意是对一组算法的封装.动态的选择需要的算法并使用. 策略模式指的是程序中涉及决策控制的一种模式.策略模式功能非常强大,因为这个设计模 ...