/* * 接口: * 1、接口也是一种引用数据类型 * 2、接口是完全抽象的。(抽象类是半抽象。)或者也可以说接口是特殊的抽象类。 * 3、接口怎么定义,语法是什么? * 不能用class 要用 interface * [修饰符列表] interface 接口名 { * } * * 定义一个类 * [修饰符列表] class 类名{ * } * * 定义一个抽象类 * [修饰符列表] abstract class 类名{ * } * * 4、接口编译之后生成的文件也是class * 5、接口支持多继承,一个接口可以继承多个接口。 * 6、接口中只包含两部分内容: * 一部分是常量、一部分是抽象方法。接口中没有其他内容了。只有以上两个部分。 * 7、接口中所有的元素都是public修饰的。(都是公开的)。 * 8、接口中的抽象方法定义时:public abstract修饰符可以省略。 * 9、接口中的方法都是抽象方法,所以接口中的方法不能有方法体。 * 10、接口中的常量public static final可以省略。 * */ public class Test01 { public static void main(String[] args) { // 访问接口常量 double PI = MyMath.PI; System.out.println(PI); // 常量可以修改吗?可以重新赋值吗? // Error:(32, 15) java: 无法为最终变量PI分配值 // MyMath.PI = 3.1415; } } interface A{ } interface B extends A{ } // 一个接口可以继承多个接口(支持多继承) interface C extends A,B{ } interface MyMath{ // 常量 // public static final double PI = 3.1415926; double PI = 3.1415926; // 抽象方法 // public abstract int sum(int a,int b); // 接口当中既然都是抽象方法,那么在编写代码的时候,public abstract 可以省略吗? int sum(int a,int b); // 接口中的方法可以有方法体吗? // Error:(52, 18) java: 接口抽象方法不能带有主体 /*void doSome(){}*/ //void doSome(); int sub(int a,int b); }
案例2:
/* * 接口的基础语法: * 1 类和类之间叫做继承,类和接口之间叫做实现。 * 别多想:你仍然你可以将实现看做继承。 * 继承使用extends关键字完成 * 实现使用implements关键字完成 * * 2 五颗星(*****): * 当一个非抽象的类实现接口的话,必须将接口中的所有的抽象方法全部实现。(覆盖/重写) * */ public class Test02 { public static void main(String[] args) { // 这里可以使用多态吗? // 父类型的引用指向子类型的对象 MyMath1 myMath1 = new MyMathImpl(); // 调用接口里面的方法(面相接口编程) int result1 = myMath1.sub(100,200); System.out.println(result1); int result2 = myMath1.sum(100,200); System.out.println(result2); } } // 特殊的抽象类,完全抽象的,叫做接口。 interface MyMath1{ // 常量 double PI = 3.1415926; // 抽象方法 int sum(int a,int b); // 抽象方法 int sub(int a,int b); } // 编写一个类(这个类是一个非抽象的类) // 这个类的名字是随意的 class MyMathImpl implements MyMath1 { /*Error:(34, 20) java: MyMathImpl中的sum(int,int)无法实现MyMath1中的sum(int,int) 正在尝试分配更低的访问权限; 以前为public int sum(int a,int b){ return a + b; }*/ // 重写/覆盖/实现 接口中的方法(通常叫做实现。) // 少些一个方法都不行 public int sum(int a,int b){ return a + b; } public int sub(int a,int b){ return a - b; } } //Error:(27, 1) java: MyMathImpl不是抽象的, 并且未覆盖MyMath1中的抽象方法sub(int,int) //class MyMathImpl implements MyMath1 {} //这样子就没有问题 因为你的类是抽象类,所以你也可以不用去实现接口中的抽象方法 //abstract class MyMathImpl implements MyMath1 { }
/* * 接口和接口之间支持多继承,那么一个类可以同时实现多个接口吗? * 对于计算机来说,一个机箱上有多个接口,一个接口是接键盘的,一个接口是接显示器的... * * 重点(五颗星*****):一个类可以同时实现多个接口。 * * 这种机制弥补了java中的那个缺陷? * Java中类和类只支持单继承。实际上单继承是为了简单而出现的,现实世界中存在多继承, * java中的接口弥补了单继承带来的缺陷 * * 接口A和接口B虽然没有继承关系,但是写代码的时候,可以互转。 * 编译器没意见,但是运行时可能出现:ClassCastException * * 之前有一个结论: * 无论向上转型还是向下转型,两种类型之间必须要有继承关系, * 没有继承关系,编译器会报错。(这句话不适用在接口方面) * 最终实际上和之前还是一样,需要加:instanceof运算符进行判断。 * 向下转型养成好习惯,转型之前先if + instanceof 进行判断。 * */ public class Test03 { public static void main(String[] args) { // 多态该怎么用? A1 a = new D(); B1 b = new D(); C1 c = new D(); // 这个编译没问题,运行也没问题 // 调用其他接口中的方法,你需要转型(接口转型)。 B1 b2 = (B1)a; b2.m2(); // 直接向下转型D可以吗?可以 D d = (D)a; d.m2(); M m = new E(); // 经过测试:接口和接口之间在进行强制转换的时候,没有继承关系,也可以进行强转。 // 但是一定要注意,运行时可能会出现ClassCastException异常。 /* Exception in thread "main" java.lang.ClassCastException: class E cannot be cast to class K (E and K are in unnamed module of loader ‘app‘) at Test03.main(Test03.java:24)*/ // 编译没问题,运行有问题,因为你的M跟K没关系 // K k = (K)m; // 应该这样去写 if(m instanceof K){ K k = (K)m; } } } interface K{} interface M{} class E implements M{} interface X{ } interface Y{ } interface Z extends X,Y{ } // 接口和接口之间支持多继承 interface A1{ void m1(); } interface B1{ void m2(); } interface C1{ void m3(); } // 实现多个接口,其实就类似于多继承。 class D implements A1,B1,C1{ public void m1() { System.out.println("m1...."); } public void m2() { System.out.println("m2...."); } public void m3() { System.out.println("m3...."); } }
案例4:继承和接口同时存在,应该怎么写:
/* * 继承和实现都存在的话,代码应该怎么写? * extends 关键字在前 * implements 关键字在后 * */ public class Test04 { public static void main(String[] args) { // 创建对象(表面看Animal类没起作用) Flyable flyable = new Cat();// 多态 flyable.fly(); // 同一个接口 Flyable flyable1 = new Pig();// 多态 // 调用同一个fly方法,最后执行效果不同。 flyable1.fly(); Flyable flyable2 = new Fish(); flyable2.fly(); } } // 动物类父类 class Animal{ } // 可飞翔的接口(是一对翅膀) // 能插拔的就是接口(没有接口你怎么插拔呢) // 内存条插到主板上,他们之间有借口,内存条可以更换 // 接口通常提取的是行为动作 interface Flyable{ void fly(); } // 动物类子类,猫类 // Flyable是一个接口,是一对翅膀的接口,通过接口插到猫身上,让猫变得可以飞翔。 class Cat extends Animal implements Flyable{ public void fly() { System.out.println("这只猫咪插上了翅膀,飞了起来!"); } } // 蛇类,如果你不想让他飞,可以不识闲Flyable接口 // 没有实现这个接口表示你没有翅膀,没有给你插上翅膀,你肯定不能飞。 class Snake extends Animal{ } // 想飞就插翅膀这个接口 class Pig extends Animal implements Flyable{ public void fly() { System.out.println("猪飞了起来!"); } } class Fish implements Flyable{// 没写extends,也是有的,默认继承Object public void fly() { System.out.println("一条鱼儿飞上了天空。"); } }
原文:https://www.cnblogs.com/xlwu/p/13121422.html