漫谈java8中接口默认方法以及java9的接口私有方法带来的变化

首先还是先重温一下抽象类和接口的区别:
接口

接口是抽象方法的集合。如果一个类实现了某个接口,那么它就继承了这个接口的抽象方法。这就像契约模式,如果实现了这个接口,那么就必须确保使用这些方法。接口只是一种形式,接口自身不能做任何事情。
我们以JDK中提供了另一个序列化接口--Externalizable为例。

public interface Externalizable extends Serializable {
 
    void writeExternal(ObjectOutput out) throws IOException;
 
    void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
}
public class Employee implements Externalizable {
//注意这种序列化必须自己实现构造方法
   public Employee () {  
        System.out.println("none-arg constructor");  
    }  
 
    int employeeId;
    String employeeName;
 
    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        employeeId = in.readInt();
        employeeName = (String) in.readObject();
 
    }
 
    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
 
        out.writeInt(employeeId);
        out.writeObject(employeeName);
    }
}

抽象类

抽象类是用来捕捉子类的通用特性的 。它不能被实例化,只能被用作子类的超类。抽象类是被用来创建继承层级里子类的模板。

public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
    // abstract method
    abstract void service(ServletRequest req, ServletResponse res);
 
    void init() {
        // Its implementation
    }
    // other method related to Servlet
}
public class HttpServlet extends GenericServlet {
    void service(ServletRequest req, ServletResponse res) {
        // implementation
    }
 
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
        // Implementation
    }
 
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
        // Implementation
    }
 
    // some other methods related to HttpServlet
}
参数 抽象类 接口
默认的方法实现 它可以有默认的方法实现 jdk1.8之前没有,现在可以使用default关键字创在interface中创建一个default方法,该方法包含了具体的实现代码,一个接口中可以有多个default方法
实现 子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有抽象的方法的实现。 子类使用关键字implements来实现接口。它需要提供接口中所有声明的非default方法的实现
构造器 抽象类可以有构造器 接口没有构造器
实例化 不能 不能
访问修饰符 抽象方法可以有public、protected和default这些修饰符 接口方法默认修饰符是public。在java9以后可以用private定义私有方法,私有方法必须包含方法体。
main方法 抽象方法可以有main方法并且我们可以运行它 接口没有main方法,因此我们不能运行它。
继承 单一继承 多继承
访问速度 它比接口速度要快 接口是稍微有点慢的,因为它需要时间去寻找在类中实现的方法。
添加新方法 如果你往抽象类中添加新的方法,你可以给它提供默认的实现。因此你不需要改变你现在的代码。 jdk1.8以后可以添加了,也就是说有一些在接口设计上的顽疾现在有了完美解决的方法

通过以上对比抽象类的使用场景被削减,那么什么时候还需要使用抽象类
1、需要构造方法。
2、独立运行。
3、定义final方法防止子类篡改。

在使用抽象类时需要注意几点:

1、抽象类不能被实例化,实例化的工作应该交由它的子类来完成,它只需要有一个引用即可。

2、抽象方法必须由子类来进行重写。

3、只要包含一个抽象方法的抽象类,该类必须要定义成抽象类。

4、抽象类中可以包含具体的方法,当然也可以不包含抽象方法。

5、子类中的抽象方法不能与父类的抽象方法同名。

6、abstract不能与final并列修饰同一个类。

7、abstract 不能与private、static、final或native并列修饰同一个方法。

在使用接口过程中需要注意如下几个问题:

1、Interface的所有方法访问权限自动被声明为public。在java9以后可以定义私有方法,但是必须有方法体不能是抽象方法。

2、接口中可以定义“成员变量”,或者说是不可变的常量,因为接口中的“成员变量”会自动变为为public static final。可以通过类命名直接访问:ImplementClass.name。

3、不能使用new操作符实例化一个接口,但可以声明一个接口变量,该变量必须引用(refer to)一个实现该接口的类的对象。可以使用 instanceof 检查一个对象是否实现了某个特定的接口。例如:if(anObject instanceof Comparable){}。

4、在实现多接口的时候一定要避免方法名的重复,尤其是default方法。

5、接口里的方法不能用final修饰

public interface SimpleInterface {
     public void doSomeWork();
      //A default method in the interface created using "default" keyword
      //使用default关键字创在interface中直接创建一个default方法,该方法包含了具体的实现代码
      default public void doSomeOtherWork(){
          getStu();
        System.out.println("DoSomeOtherWork implementation in the interface");
      }
      static void getStatic() {
          System.out.println("static method");
        }
      default public void doSomeOtherWork2(){
          getStu();
          //私有静态方法用于为接口中的默认方法服务
          getStatic1();
            System.out.println("DoSomeOtherWork2 implementation in the interface");
          }
      //java9中可以创建私有方法了
      private void getStu() {
          System.out.println( "private method!");
        }
    //java9中可以创建私有静态方法了
      private static void getStatic1() {
          System.out.println("private static method");
        }
}

class SimpleInterfaceImpl implements SimpleInterface{
 @Override
 public void doSomeWork() {
   System.out.println("Do Some Work implementation in the class");
 }
 @Override
 public void doSomeOtherWork() {
   System.out.println("Do doSomeOtherWork implementation in the class");
 }
 /*
  * Not required to override to provide an implementation 
  * for doSomeOtherWork.
  * 在SimpleInterfaceImpl里,不需要再去实现接口中定义的doSomeOtherWork方法
  */

 public static void main(String[] args) {
     SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl();
   simpObj.doSomeWork();
   simpObj.doSomeOtherWork();
   simpObj.doSomeOtherWork2();
   SimpleInterface.getStatic();
 }
}
···


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • (一)Java部分 1、列举出JAVA中6个比较常用的包【天威诚信面试题】 【参考答案】 java.lang;ja...
    独云阅读 7,140评论 0 62
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,754评论 18 399
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,868评论 18 139
  • 端午节的第一天假期,带女儿在小区里玩,邻居家带孩子的阿姨,就像发现新大陆一样,神秘兮兮地对我们说,按说,这夫妻俩人...
    苏小昨阅读 456评论 0 2
  • 今天分享的书籍是伊恩•莱斯利的《好奇心》。 一、好奇心就像一台忙碌工作的发动机,不断激发我们的想象力与创造力。 人...
    面朝大海li阅读 367评论 1 4