“核心技术:接口、lambda表达式与内部类”的版本间差异
跳到导航
跳到搜索
无编辑摘要 |
(→接口) |
||
第2行: | 第2行: | ||
== 接口 == | == 接口 == | ||
接口(interface),是对类的一组需求描述(一组行为定义): | |||
# 接口的所有方法自动属于public(不用提供public关键字); | |||
# 接口中可以有常量,但是不能有实例域; | |||
#: 即,域自动设置为:“public static final” | |||
# 接口中可以有实现方法(Java SE 8 之后),但方法中不能引用实例域; | |||
#: 默认:“public abstract” | |||
提供实例域和方法实现,应该由实现接口的类来完成。<br/> | |||
实现接口: | |||
# 声明实现给定的接口: | |||
#: <syntaxhighlight lang="java"> | |||
class Employee implements Comparable | |||
</syntaxhighlight> | |||
# 对接口中的所有方法进行定义; | |||
* 所有方法都必须有实现; | |||
* 实现方法时,必须把方法声明为“public”; | |||
=== 接口的特性 === | |||
# 接口不是类,不能用“new”进行实例化; | |||
# 可以用接口声明变量,变量只能引用接口实现类的对象; | |||
# 可以使用“instanceof”检查一个对象是否实现了某个特定接口(类似于检查对象是否属于某个类); | |||
# 接口可以被继承,用新的接口扩展旧接口; | |||
=== 接口与抽象类 === | |||
Java不支持多重继承(multiple inheritance):引入抽象类,避免多重继承的复杂性和低效性。 | |||
=== 静态方法 === | |||
Java 8 之后,允许接口中增加静态方法: | |||
* 静态方法无法实现多态,形式上重写,实际上是新方法。 | |||
=== 默认方法 === | |||
可以为接口方法提供一个默认实现(也可以不实现),并用“default”修饰该方法: | |||
# 可以不用实现接口所有方法,只关注于需要的某个或某几个方法(可以不再使用伴随类): | |||
#: <syntaxhighlight lang="java"> | |||
public interface MouseListener | |||
{ | |||
default void mousedieked(MouseEvent event) {} | |||
default void mousePressed(MouseEvent event) {} | |||
default void mouseReleased(MouseEvent event) {} | |||
default void mouseEntered(MouseEvent event) {} | |||
default void mouseExited(MouseEvent event) {} | |||
} | |||
</syntaxhighlight> | |||
# 在为旧接口增加方法时,使用默认方法可以保证“源代码兼容”(source compatible); | |||
#: (增加非默认方法,会导致接口现有实现类不能正常工作) | |||
==== 关于伴随类 ==== | |||
<pre> | |||
在JavaAPI 中,你会看到很多接口都有相应的伴随类,这个伴随类中实现了相应接口的部分或所有方法, 如 Collection/AbstractCollection 或 MouseListener/MouseAdapter。在JavaSE 8 中,这个技术已经过时。现在可以直接在接口中实现方法。 | |||
</pre> | |||
使用抽象类(伴随类)对接口进行部分实现,而后用户类并不之间实现接口(需要实现全部方法),而是继承与该抽象类(只重写需要的类即可)。如: | |||
# <syntaxhighlight lang="java"> | |||
public interface Collection<E> extends Iterable<E> { | |||
public abstract class AbstractCollection<E> implements Collection<E> { | |||
</syntaxhighlight> | |||
# <syntaxhighlight lang="java"> | |||
public interface MouseListener extends EventListener { | |||
public abstract class MouseAdapter implements MouseListener, MouseWheelListener, MouseMotionListener { | |||
</syntaxhighlight> | |||
# 又见,SpringMVC 中的拦截器(见[http://wiki.eijux.com/SpringMVC%EF%BC%9A%E9%AB%98%E7%BA%A7%E5%BA%94%E7%94%A8#.E6.8B.A6.E6.88.AA.E5.99.A8.E5.AE.9A.E4.B9.89]): | |||
#: <syntaxhighlight lang="java"> | |||
public interface HandlerInterceptor { | |||
public interface AsyncHandlerInterceptor extends HandlerInterceptor { | |||
public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor { | |||
</syntaxhighlight> | |||
=== 解决默认方法冲突 === | |||
冲突:现在接口中将一个方法定义为默认方法,又在超类或另一个接口中定义了同样的方法;<br/> | |||
规则: | |||
# 超类优先:接口中的方法(不论是否默认方法)会被忽略; | |||
# 接口冲突:一个接口提供默认方法,一个接口提供同名同参数方法(不论是否默认方法),则在实现类必须覆盖这个方法; | |||
== lambda == | == lambda == |
2020年10月17日 (六) 03:28的版本
接口
接口(interface),是对类的一组需求描述(一组行为定义):
- 接口的所有方法自动属于public(不用提供public关键字);
- 接口中可以有常量,但是不能有实例域;
- 即,域自动设置为:“public static final”
- 接口中可以有实现方法(Java SE 8 之后),但方法中不能引用实例域;
- 默认:“public abstract”
提供实例域和方法实现,应该由实现接口的类来完成。
实现接口:
- 声明实现给定的接口:
class Employee implements Comparable
- 对接口中的所有方法进行定义;
- 所有方法都必须有实现;
- 实现方法时,必须把方法声明为“public”;
接口的特性
- 接口不是类,不能用“new”进行实例化;
- 可以用接口声明变量,变量只能引用接口实现类的对象;
- 可以使用“instanceof”检查一个对象是否实现了某个特定接口(类似于检查对象是否属于某个类);
- 接口可以被继承,用新的接口扩展旧接口;
接口与抽象类
Java不支持多重继承(multiple inheritance):引入抽象类,避免多重继承的复杂性和低效性。
静态方法
Java 8 之后,允许接口中增加静态方法:
- 静态方法无法实现多态,形式上重写,实际上是新方法。
默认方法
可以为接口方法提供一个默认实现(也可以不实现),并用“default”修饰该方法:
- 可以不用实现接口所有方法,只关注于需要的某个或某几个方法(可以不再使用伴随类):
public interface MouseListener { default void mousedieked(MouseEvent event) {} default void mousePressed(MouseEvent event) {} default void mouseReleased(MouseEvent event) {} default void mouseEntered(MouseEvent event) {} default void mouseExited(MouseEvent event) {} }
- 在为旧接口增加方法时,使用默认方法可以保证“源代码兼容”(source compatible);
- (增加非默认方法,会导致接口现有实现类不能正常工作)
关于伴随类
在JavaAPI 中,你会看到很多接口都有相应的伴随类,这个伴随类中实现了相应接口的部分或所有方法, 如 Collection/AbstractCollection 或 MouseListener/MouseAdapter。在JavaSE 8 中,这个技术已经过时。现在可以直接在接口中实现方法。
使用抽象类(伴随类)对接口进行部分实现,而后用户类并不之间实现接口(需要实现全部方法),而是继承与该抽象类(只重写需要的类即可)。如:
public interface Collection<E> extends Iterable<E> { public abstract class AbstractCollection<E> implements Collection<E> {
public interface MouseListener extends EventListener { public abstract class MouseAdapter implements MouseListener, MouseWheelListener, MouseMotionListener {
- 又见,SpringMVC 中的拦截器(见[1]):
public interface HandlerInterceptor { public interface AsyncHandlerInterceptor extends HandlerInterceptor { public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor {
解决默认方法冲突
冲突:现在接口中将一个方法定义为默认方法,又在超类或另一个接口中定义了同样的方法;
规则:
- 超类优先:接口中的方法(不论是否默认方法)会被忽略;
- 接口冲突:一个接口提供默认方法,一个接口提供同名同参数方法(不论是否默认方法),则在实现类必须覆盖这个方法;