【 java 面向对象】接口、JD7/JD8
前言
这一节我写一点java面向对象中比较重要的一部分:接口,也意味着面向对象系列即将完工!
接口概述
- 一方面,有时必须几个类中派生出一个子类,继承它们所有的属性和方
法。但是, Java 不支持多重继承,有了接口,就可以得到多重继承的效果。 - 另一方面,有时必须从几个类中抽取出一些共同的行为特征,而它们之间又没有关系,仅仅是具有相同的行为特征而己。例如:鼠标、键盘、打印机、扫描仪、摄像头、充电器、MP3机、手机、数码相机、移动硬盘等都支持 USB 连接。
- 接口就是规范,定义的是一组规则,体现了现实世界中“如果你是要...则必须能..”的思想。继承是一个”是不是”的关系,而接口实现则是”能不能”的关系。
- 接口的本质是契约,标准,规范,就像我们的法律一样。制定好后大家都要遵守。
定义接口
1.接口使用 interface 来定义
2.Java中,接口和类是并列的两个结构
JDK7
JDK7及以前:只能定义全局常量和抽象方法
全局常量: public static final 的。但是书写时,可以省略不写。
抽象方法: public abstract 的,书写时可省略。
interface A{
public static final int x = 1;
int y = 2; //省略public static final
public abstract void method1();
void method2(); //省略public abstract
}
JDK8
JDK8,除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法
从技术角度来说,这是完全合法的,只是它看起来违反了接口作为一个抽象定义的理念。
- 静态方法:使用 static 关键字修饰。可以通过接口直接调用静态方法,并执行其方法体。我们经常在相互一起使用的类中使用静态方法。你可以在标准库中找到像 Collection / Collections 或者 Path / Paths 这样成对的接口和类。
默认方法:默认方法使用 default 关键字修饰。可以通过实现类对象来调用。我们在已有的接口中提供新方法的同时,还保持了与旧版本代码的兼容性。比如: java 8API中对 Colection 、 List 、 comparator 等接口提供了丰富的默认方法。默认方法也可以被重写。
interface A{
//JDK7
public static final int x = 1;
int y = 2; //省略public static final
public abstract void method1();
void method2(); //省略public abstract
//JDK8
public static void method3() {
System.out.println("接口中的静态方法!");
}
public default void method4(){
System.out.println("接口中的默认方法!");
}
}
接口的实现
接口中不能定义构造器的!意味着接口不可以实例化
Java开发中,接口通过让类去实现==( implements )==的方式来使用。
- 如果实现类盖了接口中的所有抽象方法,则此实现类就可以实例化。
如果实现类没有覆盖接口中所有的抽象方法,则此实现类仍为一个抽象类。
interface A{
//JDK7
public static final int x = 1;
int y = 2; //省略public static final
public abstract void method1();
void method2(); //省略public abstract
//JDK8
public static void method3() {
System.out.println("接口中的静态方法!");
}
public default void method4(){
System.out.println("接口中的默认方法!");
}
}
class B implements A{
@Override
public void method1() {
System.out.println("重写的抽象方法1");
}
@Override
public void method2() {
System.out.println("重写的抽象方法2");
}
@Override
public void method4() {
// 接口中默认方法的调用
A.super.method4();
System.out.println("重写的默认方法");
}
}
创建接口的匿名实现类
前面我们在讲抽象类时写过怎样创建抽象类的匿名子类,这里同样的,我们也可以创建接口的匿名实现类。
// 创建接口的匿名实现类 ---A是接口
A a = new A(){
@Override
public void method1() {
System.out.println("接口的匿名实现类重写的抽象方法一");
}
@Override
public void method2() {
System.out.println("接口的匿名实现类重写的抽象方法二");
}
// 接口的匿名实现类重写的默认方法
@Override
public void method4() {
A.super.method4(); //在接口的实现类中调用接口未重写的默认方法
System.out.println("接口的匿名实现类重写的默认方法");
}
};
完整Demo
package 接口;
public class Demo {
public static void main(String[] args) {
B b = new B();
// 接口中抽象方法的调用
System.out.println("------接口中抽象方法的调用------");
b.method1();
b.method2();
// 接口中静态方法的调用
System.out.println("------接口中静态方法的调用------");
A.method3();
// 接口中默认方法的调用(若重写了默认方法,则调用重写的)
System.out.println("------接口中默认方法的调用------");
b.method4();
// 接口中全局常量调用
System.out.println("------接口中全局常量调用------");
System.out.println(A.x + " " + A.y);
// 创建接口的匿名实现类
System.out.println("------接口的匿名实现类------");
A a = new A(){
@Override
public void method1() {
System.out.println("接口的匿名实现类重写的抽象方法一");
}
@Override
public void method2() {
System.out.println("接口的匿名实现类重写的抽象方法二");
}
// 接口的匿名实现类重写的默认方法
@Override
public void method4() {
A.super.method4(); //在接口的实现类中调用接口未重写的默认方法 // 注意是接口名.super
System.out.println("接口的匿名实现类重写的默认方法");
}
};
// 匿名实现类种方法的调用
a.method1();
a.method2();
a.method4();
}
}
interface A{
//JDK7
public static final int x = 1;
int y = 2; //省略public static final
public abstract void method1();
void method2(); //省略public abstract
//JDK8
public static void method3() {
System.out.println("接口中的静态方法!");
}
public default void method4(){
System.out.println("接口中的默认方法!");
}
}
class B implements A{
@Override
public void method1() {
System.out.println("重写的抽象方法1");
}
@Override
public void method2() {
System.out.println("重写的抽象方法2");
}
@Override
public void method4() {
// 接口的实现类中的未重写的接口默认方法的调用
A.super.method4(); // 注意是接口名.super
System.out.println("重写的默认方法");
}
}
其他补充
- java类可以实现多个接口—>弥补了 Java 单继承性的局限性
格式: class AA extends BB implements CC , DD , EE - 接口与接口之间可以继承,而且可以多继承。
- 接口的具体使用,体现多态性。
- 接口,实际上可以看做是一种规范。
- 如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的默认方法,那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法。->类优先原则
- 如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,那么在实现类没有重写此方法的情况下,报错。–>接口冲突。这就需要我们必须在实现类中重写此方法。
- 如果一个类既有父类,又实现了接口,在父类和接口中各有一个同名的变量。那么子类输出这个变量是时也会报错,此时输出的这个变量是不明确的!
结语
如果你觉得博主写的还不错的话,可以关注一下当前专栏,博主会更完这个系列的哦!留个小尾巴《病历证明》
还没有评论,来说两句吧...