接口

接口##

接口,可以用于 规范实现接口的类中必须实现接口中抽象方法。接口可以理解为一种契约使用关键字interface定义接口

public interface 会飞的 { 
public void 起飞(); //没有具体实现,也无法定义具体实现,这里是抽象方法 
public void 巡航飞行();
public void 降落(); }
  • 抽象类中的抽象方法不能省略abstract关键字,但是接口中的方法声明可以添加abstract,也可以不写

  • 接口不能直接使用,必须有对应的实现类

    public class 飞机类 implements 会飞的 { //共性是通过实现接口来表示的 
    private String name; //名称,这是类属的属性,这里可以定义字节类的成员,和接口无关 //如果当前类不是抽象类,则必须实现接口中的所有抽象方法 
    public void 起飞() { 
    System.out.println("使劲的跑,一抬头就飞起来了"); }
    public void 巡航飞行() { 
    System.out.println("使劲的烧油..."); 
    }
    public void 降落() {
    System.out.println("我对准...");
    }
    }
    

通过接口定义变量,使用具体类的实例,进行调用

 会飞的 obj = new 飞机类(); //飞机类中必须提供接口中的所有抽象方法的实现,否则类只能是抽象类 obj.起飞(); //因为变量是通过接口进行声明的,所以只能调用接口中声明的方法,不能直接调用实现类中的没 有在接口中声明过的方法 
 obj.巡航飞行(); 
 obj.降落();

引入接口的目的在于隔离实现

什么是接口

在Java中不直接支持多继承,因为会出现调用的不确定性,所以Java将多继承机制进行改良,在Java中变成了多实现。一个类只能有一个直系双亲类,一个类可以实现多个接口,一个接口可以继承多个接口

interface IA{}
interface IB{}
interface IC extends IA,IB{} 正确的,其中IC中的方法等于IA+IB 
class A implements IA,IB{} 
IA a=new A(); 
IB b=new A();
  • 没有构造器方法,不能定义静态或者非静态代码块
public interface IA{
public IA(){} //语法报错 
}

没有属性,只能定义常量

public class Test { 
    public static void main(String[] args) {                 System.out.println(IA.name); //常量可以直接使用
                                            System.out.println(B.name); //实现类也可以直接访问常量 
   }
}
interface IA { //private int age;语法报错,提示信息为Illegal modifier for the interface field IA.name; only public, static & final are permitted 
String name = "zzz";// 接口中只能定义常量,不能定义属性,默认限定词public static final,自定义限定词不能冲突 
}
 class B implements IA{} //访问常量既可以通过接口IA和实现类B名称的方式直接访问,例如 B.name。也可以通过B对象的方式进行访,例如new B().name

可以包含抽象方法,也可以没有抽象方法

interface IA1 {
}// 这个接口中没有包含任何抽象方法。如果一个接口中没有定义抽象方法,这种接口也叫做旗标接口、标 志接口 
class A1Impl implements IA1 {
}
interface IA2{//接口的限定词同类定义一致 
  int ee();//抽象方法,默认public abstract int ee(); 
   public void pp();//方法的限定词可以是public, abstract, default, static,前面的public 可以省略,如果不写默认public 
    public abstract void cc();//这里abstract可以省略,默认就是abstract //在JDK1.8中引入特殊关键字default,允许在接口中提供方法的默认实现 
    public default void dd(){ //这个方法的调用时必须有实现类,否则无法创建对象,例如new IA2()语法错误,也允许在实现类中覆盖定义 
    System.out.println("dddd...."); 
 }
//在JDK1.8中允许在接口中定义静态方法 
public static void ff(){ //这个静态方法可以通过接口名称直接调用 IA2.ff(),同时允许 在实现类中重新定义,但是不能通过IA2 a=new AImpl(); a.ff()的方式进行调用 
    System.out.println("ffffff"); 
   } 
}

接口允许多重继承,也允许一个类实现多个接口

public class Person {
public static void main(String[] args) { 
IC cc=new CImpl(); 
cc.pp();
  }
}
interface IA{
public default void pp() { 
System.out.println("this is IA.pp() default");
    }
}
interface IB{
public default void pp() {
System.out.println("this is IB.pp() default");
    } 
}
//因为在两个父接口中都定义了pp方法的默认实现,则在子接口无法确定到底使用哪个,所以要求子接口必 须明确说明 interface IC extends IA,IB{
@Override
default void pp() { //在子接口中覆盖定义
    System.out.println("this is IC.pp() default"); IA.super.pp();//调用IA接口所定义的pp方法 
    IB.super.pp(); 
}
}
class CImpl implements IC{}
public class Person {
public static void main(String[] args) { 
    IA cc=new CImpl();
     cc.pp();
}
}
interface IA{
      public default void pp() { 
       System.out.println("this is IA.pp() default"); 
  } 
}
interface IB{
     public default void pp() {
         System.out.println("this is IB.pp() default"); 
 }
}
//报错的原因是IA和IB接口中有相同的方法定义,同时又有默认实现,则CImpl类不知道使用哪个默认实 现,所以要求类中必须明确说明
class CImpl implements IA,IB{
 @Override
  public void pp() { 
     System.out.println("可以定义自己的逻辑");            IA.super.pp();//也允许调用某个接口中的默认实现 IB.super.pp(); 
} 
}

抽象方法必须在实现类中提供实现

class A2Impl implements IA2{ //在实现类中必须实现接口中的所有抽象方法,否则当前类只能是抽 象类 
public int ee() { 
return 0; 
}
public void pp() { System.out.println("A2Impl....");
}
public void cc() { System.out.println("A2Impl....."); 
}//dd方法由于在接口中有默认实现,所以可以不用重新定义,也允许重新定义 
}
  • 可以使用default关键字给抽象方法提供默认实现,有默认实现的方法在实现类中可以重新定义,也可以不重新定义

报错原因:Java中不支持类的多重继承,一个类只能有一个双亲类

接口允许多重继承###

一个类在继承另一根类时,还可以实现多个接口。

public class Person { 
public static void main(String[] args) {
IA a1=new AImpl();
B a2=new AImpl();
a1.pp();
}
}
interface IA{
public void pp();
}
class B {
public void pp() {
System.out.println("this is B.pp()");
}
}
class AImpl extends B implements IA{ //AImpl类是通过继承B类实现了对接口IA中的抽象方法提供实现
}
public class Person {
public static void main(String[] args) {
IA a1=new AImpl();
a1.pp();
IB a2=new AImpl();
a2.pp();
}
}
interface IA{
public void pp();
}
interface IB {
public default void pp() { 
System.out.println("this is B.pp()"); 
} 
}
class AImpl implements IA,IB{ //不能因为IB中针对pp方法提供了默认实现,所以不在实现类中定义pp方法 
@Override public void pp() { 
System.out.println("添加的新的处理逻辑");
// IA.super.pp(); 因为IA接口中并没有提供pp的默认实现,所以不允许这样调用 
IB.super.pp(); 
}
}

类是单根继承,不允许继承多个父类

允许一个类实现多个接口,但是每个接口的抽象方法都必须提供实现,否则是抽象类。提供的实现也可以是继承

public class A1{
    public void p1(){}
}
public class A2 extends A1 implements IA1,IA2{          public void p2(){} 
}
public abstract class A3 extends A1 implements IA1,IA2{} //因为p2方法没有实现

接口的出现避免了单继承的局限性,这样定义C接口则拥有A+B的所有定义,可以使用A和B接口以及父类D声明变量类型,直接new T。但是约束时,用谁声明变量编译器系统识别就是谁这种类型,也就意味只能调用识别类型中的方法,不能调用其他方法

interface A{
public void p1();
}
interface B{ 
public void p2();
}
interface C extents A,B{}
class D{ 
public void abc(){}
}
class T extends D implements C{
public void p1(){}
public void p2(){} 
}
D d=new T();这里只能直接调用abc方法,如果使用其他方法则需要进行类型转换
A a=new T();这里只能直接调用A接口中声明的方法
p1 B b=new T();这里只能直接调用B接口中声明的方法
p2 C c=new T();

声明接口的语法

访问修饰符 interface 接口名{ } 一般建议接口名称使用形容词

  • 如果定义public接口,则规则和定义public类一致,要求接口名称和文件名称一致
  • 外部的接口只能使用public、默认这两个范围限定词;如果定义内部接口则可以使用4大范围限定词
  • 接口实际上提供了同一的操作界面(方法),如果是JDK1.8-版本则一个方法也不实现,等待某类或某几个类去实现它的方法【接口中的所有方法必须是抽象的】。如果使用的是JDK1.8+允许使用default在接口中定义默认实现,这个实现允许在实现类中重新定义覆盖
public class Test1 {
public static void main(String[] args) {
IA2 a2=new A2Impl(); 
a2.pp(); 
}
}
interface IA2 { 
default void pp(){ //通过defaul在接口中定义方法的默认实现,则在实现类中可以覆盖定义,也 可以继承使用System.out.println("this is pp....");
this.ff();
    }
    void ff();
}
class A2Impl implements IA2{
    public void ff() {
        System.out.println("this is ff...");
    }
}

default默认方法实现使用的限制

public class Test1 {
    public static void main(String[] args) {
        IA2 a2 = new A2Impl(); a2.pp(); 
    } 
}
interface IA2 {
    default void pp() {
        System.out.println("this is No2 pp....");
    } 
}
interface IA3 {
    default void pp(){
        System.out.println("this is No3 pp"); 
    }
}
class A2Impl implements IA2, IA3 {//如果IA2中有一个default实现的方法和IA3中的方法一致,则 必须在实现类中重新定义 
    public void pp() { 
        IA2.super.pp();//调用IA2接口中的pp方法的默认实现 
        IA3.super.pp(); 
    }
}
  • 接口中没有属性,只能定义常量,它提供一些常量,实现它的类可以共享这些常量
  • 接口可以给出访问控制符,用public修饰的是公共接口,到处可见;如果定义接口没有范围限定词,则只能在同包中访问

接口中只能定义常量和抽象方法

  • 这是JDK1.8以前版本的规则,不是最新的
  • 接口中只能定义公共的常量,接口中的属性默认是public static final类型的,必须是public static final类型的
interface IA{
    String name="vvv";//这里实际上是常量定义,不是属性,它的限定词是public static final  String name="vvv",必须在声明的同时进行赋值 }
    //在接口中不能定义静态块 static{}
    //接口中不能定义构造器
  • 接口中只能定义公共的抽象方法, 只有在JDK1.8+中可以使用default关键字定义方法实现。接口中的方法默认 是public abstract类型的,而且必须是public abstract类型的。只有在JDK1.8+中可以使用default关键字定义方法默认实现,同时允许在实现类中覆盖重新定义
  • 接口不能被实例化,只能通过实现类所实现,但是可以用于声明变量的类型。

接口 变量名=new 实现接口类();

  • 接口没有构造函数

  • 接口中的抽象方法必须在非抽象子类中提供实现,这个实现可以是继承来的

一个类实现接口的语法###

class 类名称 implements 接口名称 { }

  • 接口抽象方法的默认修饰符为public,在实现接口时必须用public关键字在方法头上说明
interface IA2 { 
void pp();
}
class B2 implements IA2 {
void pp() {
//语法报错,因为IA2接口中的方法为public abstract 
}
}
  • 一个接口可以被多个子类实现。一个子类还可以实现多个接口

类实现接口

  • 一个类在实现某接口的抽象方法时,必须使用完全相同的方法头public
  • 如果一个类实现多接口,用逗号隔开
  • 如果一个类实现了声明相同方法的两个接口,则被多个接口共用
public class Test1 { 
    public static void main(String[] args) {
        IA2 a2=new B2();
        a2.pp(); 
        IA3 a3=new B2();
        a3.pp();
    }
}
interface IA2 {
    void pp(); 

}
interface IA3{ 
    void pp(); 
}
class B2 implements IA2,IA3 {
    public void pp() {
        System.out.println("this is B2.pp()");
      } 
}

类在实现接口时可以定义它自己的附加成员,这也是最常见的形式

  • 只需在接口中定义并赋值,此后不能再修改
  • 在类中说明是接口的实现类,就可以使用该接口的常量了

接口和抽象类的异同点

  • 相同点:都是不断向上抽取而来的

  • 不同点:

    抽象类需要被继承,而且只能单继承

​ 接口需要被实现,而且可以多实现

  • 抽象类中可以定义抽象方法和非抽象方法,子类继承后可以直接使用非抽象方法
  • 接口中只能定义抽象方法,必须由子类去实现;JDK1.8+中允许接口中的方法有默认实现,实现类中可以直接使用默认实现,允许覆盖定义
  • 抽象类的继承是is a关系,在定义该体系的基本共性内容
  • 接口的实现是like a关系,在定义体系额外功能
  • 接口中只能定义常量,而且必须被初始化,抽象类中可以定义属性,允许在声明时直接初始化,也可以不初始化,同时允许定义常量

接口中的方法必须全部是抽象的(JDK1.8+版本中可以通过default关键字定义方法的默认实现,允许定义静态方法),抽象类中可以有抽象方法也可以有普通方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值