JDK1.8新特性default,static用法
在1.8以前,我们的Interface之中通常除了抽象方法别的什么都没有,但是从1.8引入开始Interface中还可以有具体的实现!其中所要用到的两个非常重要的关键字就是:default和static
default修饰的默认方法,可以带有具体的实现,同时这个接口的实现类可以不去实现这个方法就能够使用,当然也可以自己去实现这个方法(如果有必要的话)。
例:
UserService接口
public interface UserService {
String saySomething();
default String sayHello(){
return "ok I just say hello";
};
}
UserServiceImpl实现:
public class UserServiceImpl implements UserService{
@Override
public String saySomething() {
return "I have nothing to say";
}
public static void main(String args[]){
UserService user = new UserServiceImpl();
System.out.println(user.saySomething());
System.out.println(user.sayHello());
}
}
运行后输出结果:
I have nothing to say
ok I just say hello
同样也可以去实现这个默认方法:
public class UserServiceImpl implements UserService{
@Override
public String saySomething() {
return "I have nothing to say";
}
@Override
public String sayHello(){
return "I want to say something more...";
}
public static void main(String args[]){
UserService user = new UserServiceImpl();
System.out.println(user.saySomething());
System.out.println(user.sayHello());
}
}
运行结果:
I have nothing to say
I want to say something more...
调用的是子类的实现。
static的使用:
UserService接口:
public interface UserService {
String saySomething();
default String sayHello(){
return "ok I just say hello";
};
static String staticFunction(){
return "this is a inteface static function";
}
}
UserServiceImpl实现:
public class UserServiceImpl implements UserService{
@Override
public String saySomething() {
return "I have nothing to say";
}
@Override
public String sayHello(){
return "I want to say something more...";
}
public static void main(String args[]){
UserService user = new UserServiceImpl();
System.out.println(user.saySomething());
System.out.println(user.sayHello());
System.out.println(UserService.staticFunction());
}
}
运行结果:
I have nothing to say
I want to say something more...
this is a inteface static function
根平常的static方法调用一样。
但是当一个类实现了两个接口,这两个接口中有相同名字的默认方法,将会报编译错误。
补充:
既然可以有static方法,而且接口默认方法是public的,那么是不是可以在接口中定义main方法来执行呢?
实验:
public interface UserService {
String saySomething();
default String sayHello(){
return "ok I just say hello";
};
static String staticFunction(){
return "this is a inteface static function";
}
static void main(String args[]){
System.out.println("inter face run");
}
}
结果:运行成功,输出:
inter face run
同时在实现类中也同样可以调用:
public class UserServiceImpl implements UserService{
@Override
public String saySomething() {
return "I have nothing to say";
}
@Override
public String sayHello(){
return "I want to say something more...";
}
public static void main(String args[]){
UserService user = new UserServiceImpl();
System.out.println(user.saySomething());
System.out.println(user.sayHello());
System.out.println(UserService.staticFunction());
UserService.main(null);
}
}
运行结果:
I have nothing to say
I want to say something more...
this is a inteface static function
inter face run
JDK 1.8中接口和抽象类的区别
由于接口引入了接口和静态方法,这里就很容易联想到抽象类。好像两个的功能基本一样。但是其实也有不同。
- 一个类可以实现多个接口,但最多只能实现一个抽象类。
- 接口中的实例变量是默认是final的,并且只能用public,static,final修饰,static而抽象类中的实例变量则没有这以要求。
- 接口中的方法默认都是public的,而抽象类中的方法可以规定不同的作用域。
- 接口的实现必须实现所有的抽象方法(默认方法除外),而子类继承自抽象类可以不用实现所有的抽象方法。
- 接口中不能有构造方法,抽象类中可以有构造方法。
- 从设计层面上来讲:接口是对行为的规范,用于描述行为的一种抽象,而抽象类是对类的抽象,是一种模板式的设计,同时抽象类的继承含有a is b的意义在里面。
区别虽然多,但是似乎对于用起来很容易用混,到底用什么我觉得还是取决于:1)设计层面上到底是对于类的抽象还是行为的规范。2)是否需要考虑到作用域的问题。