java的接口是经过interface来实现java
为何要有接口?面试
java没有多继承 能够用接口来实现多继承的功能 由于类是两个相同事物的共性抽取出来的,接口能够 看作是两个不一样事物的某一个特性抽取出来. eg: 小东和牧羊犬都会吃饭,难道他们俩是同一类事物吗? 确定不是的.那么他们都会吃饭的这个特性就能够抽取成一个接口来使用 接口说白了也便是 完成类所不合理的一些特征而存在的 弥补类的短板
接口的特征服务器
接口的方法不能有方法体
* * 1:接口的使用 * interface 来定义 * * 2: java中 接口和类是并列的两个结构 * * 3 : 定义接口中的成员 * jdk7 以及之前 : 接口中只能定义全局常量和抽象方法 * > 全局常量: public static final :可是书写是经常省略 public static fianl * > 抽象方法: public abstract * * jdk8: 除了定义全局常量和抽象方法以外,还能够定义静态方法, 默认方法 * * * 4 : 接口中不能定义构造器,也就是不能被实例化 * * 5: 在java开发中几口经过让类去实现(implements)的方式来使用, * 若是实现类 覆盖了接口中的全部抽象方法,则此实现类就能够实例化 * 若是实现类没有重写完全部的抽象方法,则此实现类仍是一个抽象类 * * * * 6: java类实现多个接口 -----> 弥补了java单继承性的局限性 * 格式 : class AA implements BB, CC, DD, EE * * * 7: 接口与接口之间能够继承,并且能够多继承 * * 8: 接口的具体使用: 体现了多态 * * 9: 接口实际上能够看作是一种规范
面试题:网络
排错ide
interface A { int x = 0; } class B { int x = 1; } class C extends B implements A { public void pX() { System.out.println(x); } public static void main(String[] args) { new C().pX(); } }
pX() 方法的x没有声明形参,因此此处有问题
interface Playable { void play(); } interface Bounceable { void play(); } interface Rollable extends Playable, Bounceable { Ball ball = new Ball("PingPang"); } class Ball implements Rollable { private String name; public String getName() { return name; } public Ball(String name) { this.name = name; } public void play() { ball = new Ball("Football"); System.out.println(ball.getName()); } }
Rollable接口中没有重写 继承来的接口中的方法,
Ball 中的ball属性是不能重写定义的 由于此变量是在Rollable 接口中定义的 ,
接口中的变量时常量是不能够被改变的
练习题测试
定义一个接口用来实现两个对象的比较。 interface CompareObject{
public int compareTo(Object o); //若返回值是 0 , 表明相等; 若为正数,表明当前对象大;负数表明当前对象小
}
定义一个Circle类,声明redius属性,提供getter和setter方法 定义一个ComparableCircle类,继承Circle类而且实现CompareObject接口。在 ComparableCircle类中给出接口中方法compareTo的实现体,用来比较两个圆的半 径大小。 定义一个测试类InterfaceTest,建立两个ComparableCircle对象,调用compareTo 方法比较两个类的半径大小。 思考:参照上述作法定义矩形类Rectangle和ComparableRectangle类,在 ComparableRectangle类中给出compareTo方法的实现,比较两个矩形的面积大小
import java.util.Date; public class XiTest { public static void main(String[] args) { ComparableCir c1 = new ComparableCir(3.4); ComparableCir c2 = new ComparableCir(3.6); int compareValue = c1.compareTo(c2); if(compareValue >0){ System.out.println("c1比c2大"); }else if (compareValue < 0){ System.out.println("c2对象大"); }else{ System.out.println("同样大"); } } } interface CompareTest{ public int compareTo(Object o); } class Cir{ double redius; public Cir(double redius){ this.redius = redius; } public double getRedius() { return redius; } public void setRedius(double redius) { this.redius = redius; } } class ComparableCir extends Cir implements CompareTest{ public ComparableCir(double redius){ super(redius); } @Override public int compareTo(Object o){ if(this.getRedius() == 0){ return 0; } if(o instanceof ComparableCir){ ComparableCir comparableCir = (ComparableCir) o; if(this.getRedius() > comparableCir.getRedius()){ return 1; }else if(this.getRedius() < comparableCir.getRedius()){ return -1; }else{ return 0; } }else{ return 0; } } }
接口的代理模式:this
/** * 接口的应用: 代理模式 */ // 虽然是经过代理类对象去掉方法可是 实际把被代理类对象传递进去 包含了 被代理类对象 public class NetWorkTest { public static void main(String[] args) { ServerTest serverTest = new ServerTest(); ProxyServerTest proxyServerTest = new ProxyServerTest(serverTest); proxyServerTest.browse(); // 联网实现的一些检查工做 , 真实的服务器访问网络 } } interface NetWork{ public void browse(); } // 被代理类 class ServerTest implements NetWork{ @Override public void browse(){ System.out.println("真实的服务器访问网络"); } } // 代理类 class ProxyServerTest implements NetWork{ private NetWork work; public ProxyServerTest(NetWork work){ this.work = work; } public void check(){ System.out.println("联网实现的一些检查工做"); } public void browse(){ check(); work.browse(); } }
java8中接口的特性spa
java8中能够书写:
静态方法带方法体,
默认方法
* java8中接口除了定义全局常量和静态方法中 * * > 接口中定义的静态方法只能接口去调用 * > 若是子类(或者实现类)继承的父类和实现的接口中有同名同参数的方法,那么子类在没有重写此方法的状况下调用的是父类中同名同参数的方法---->类优先原则
若是实现类实现了多个接口,而多个接口中定义了同名同参数的默认方法,那么在实现类没有重写此方法的时候就会报错,---->接口冲突
* 那么咱们就必须在实现类中重写此方法
eg:代理
public class J8 { public static void main(String[] args) { CompareA compareA = new CompareA(); // compareA.method1() 报错 java8中接口中的静态方法只能接口本身调用 其余的实现类不能够去调用 //经过实现类的对象能够调用默认方法, 若是重写后接口中的方法 那么调用的是实现类内的重写方法 Java8.method1(); compareA.method2(); compareA.method3(); // 继承的父类也有 实现的接口中也有此方法那么调用的是父类中的方法 TestB testB = new TestB(); // testB.method1(); 静态方法只能够本身调用不能够实现类去调用 } } /** * java8中接口除了定义全局常量和静态方法中 * * > 接口中定义的静态方法只能接口去调用 * > 若是子类(或者实现类)继承的父类和实现的接口中有同名同参数的方法,那么子类在没有重写此方法的状况下调用的是父类中同名同参数的方法---->类优先原则 */ interface Java8{ // 静态方法 public static void method1(){ System.out.println("java8的新特性接口中的方法是能够有方法体的"); } // 默认方法 public default void method2(){ System.out.println("java8接口新特性"); } //默认方法 default void method3(){ System.out.println("java8接口新特性"); } } class CompareA extends SuperClass implements Java8 { } class SuperClass { public void method3(){ System.out.println("我是父类中的method3"); } }
在调用是接口中的静态方法只能接口自己本身去调用,以下 实现类只能够调用默认方法code
若是实现类实现了多个接口,而多个接口中定义了同名同参数的默认方法,那么在实现类没有重写此方法的时候就会报错,---->接口冲突
* 那么咱们就必须在实现类中重写此方法
由于上面定义了 TestB接口定义了method3()方法 而实现类实现了TestB和TestA接口 又没有重写method3方法就会报错
在实现类中调用接口中的被重写的方法
接口.super.方法()
eg:
class TestB extends TestD implements TestA, TestC{ public void method3(){ //重写的时候权限必须大于上一级 System.out.println("TestB 重写方法");
TestA.super.method3(); //调用接口中的默认方法 }
总结:
若一个接口中定义了一个默认方法,而另一个接口中也定义了一个同名同 参数的方法(无论此方法是不是默认方法),在实现类同时实现了这两个接 口时,会出现:接口冲突。
解决办法:实现类必须覆盖接口中同名同参数的方法,来解决冲突。
若一个接口中定义了一个默认方法,而父类中也定义了一个同名同参数的非 抽象方法,则不会出现冲突问题。由于此时遵照:类优先原则。接口中具备 相同名称和参数的默认方法会被忽略。
解决接口冲突
interface Filial{ //孝顺的 default void help(){ System.out.println("老妈我来救你"); } } interface Spoony{ //痴情的 default void help(){ System.out.println("媳妇别怕 我来了"); } } class father{ public void help(){ System.out.println("先救你妈妈"); } } class man extends father implements Filial, Spoony { @Override public void help(){ System.out.println("我该怎么办"); super.help(); Filial.super.help(); Spoony.super.help(); } }