接口

本文详细介绍了Java中的接口,强调接口作为类行为规范的作用。通过接口,定义了类必须实现的方法,但不规定具体实现。接口支持运行时动态方法解析,克服了静态类继承的局限。文中展示了接口定义、实现接口的语法,并给出了多个示例,包括单一接口实现、多个接口实现和接口类型的变量使用。
部署运行你感兴趣的模型镜像

3.8 接口 上一节 本章开头

  用关键字interface,你可以从类的实现中抽象一个类的接口。也就是说,用interface,你可以指定一个类必须做什么,而不是规定它如何去做。接口在语句构成上与类相似,但是它们缺少实例变量,而且它们定义的方法是不含方法体的。实际上,这意味着你可以定义不用假设它们怎样实现的接口。一旦接口被定义,任何类成员可以实现一个接口。而且,一个类可以实现多个接口。

  要实现一个接口,接口定义的类必须创建完整的一套方法。然而,每个类都可以自由的决定它们自己实现的细节。通过提供interface关键字,Java允许你充分利用多态性的“一个接口,多个方法”。

  接口是为支持运行时动态方法解决而设计的。通常,为使一个方法可以在类间调用,两个类都必须出现在编译时间里,以便Java编译器可以检查以确保方法特殊是兼容的。这个需求导致了一个静态的不可扩展的类环境。在一个系统中不可避免会出现这类情况,函数在类层次中越堆越高以致该机制可以为越来越多的子类可用。接口的设计避免了这个问题。它们把方法或方法系列的定义从类层次中分开。因为接口是在和类不同的层次中,与类层次无关的类实现相同的接口是可行的。这是实现接口的真正原因所在。

注意:接口增添了很多应用程序所需的功能。在一种语言例如C++中这些应用程序通常借助于多重继承来完成。

4.8.1 接口定义

  接口定义很像类定义。下面是一个接口的通用形式:

访问类型 interface 接口名 { //定义抽象类

 final 数据类型 成员名称1 = 常量; //数据成员必须赋初值

 abstract 返回值的数据类型 方法名称(参数表); //注意抽象方法里没有处理的方式

}

  这里,“访问类型”要么是public,要么就没有用修饰符。当没有访问修饰符时,则是默认访问范围,而接口是包中定义的惟一的可以用于其他成员的东西。当它声明为public时,则接口可以被任何代码使用。接口名可以是任何合法的标识符。注意定义的方法没有方法体。它们以参数列表后面的分号作为结束。它们本质上是抽象方法;在接口中指定的方法没有默认的实现。每个包含接口的类必需实现所有的方法。

  接口声明中可以声明变量。它们一般是final 和static型的,意思是它们的值不能通过实现类而改变。它们还必须以常量值初始化。如果接口本身定义成public ,所有方法和变量都是public的。

  下面列举一实例来说明接口定义的方式。假设定义了一个接口iShape2D,可以利用它来实现二维的几何图形CCircleCRectangle。对二维的几何形状而言,面积是很重要的计算,因此,可以把计算面积的method声明在接口里,而计算圆面积的pi值是常量,所示可以把他声明在接口的数据成员里。依据这两个概念,我们可以编写出如下的接口。

interface iShape2D //定义接口 
{
  final double pi=3.14;  //数据成员一定要初始化
  abstract void area();  //抽象方法,不需要定义处理方式(类体)
}

  如前所述,在上面的范例中,Java也许省略了finalabstract关键字,编程如下的程序代码:

interface iShape2D //定义接口 
{
  double pi=3.14;  //数据成员一定要初始化
  void area();  //抽象方法,不需要定义处理方式
}

  如此一来,每一个接口实现的类必须在类内部定义method的方法,且可自由地使用pi值。

  既然接口里只有抽象方法,他只要声明而不用定义处理方式,于是我们自然可以联想到接口也没有办法像一般类一样,用new运算符直接产生对象。相反地,我们必须利用接口的特性来打造一个新的类,在用它来创建对象。利用接口打造新的类的过程,我们称之为接口的实现

4.8.2 实现接口

  一旦接口被定义,一个或多个类可以实现该接口。为实现一个接口,在类定义中包括implements 子句,然后创建接口定义的方法。一个包括implements 子句的类的一般形式如下:

访问类型 class 类名 [extends 超类名] implements 接口名称{

  // 类体

}

  这里,访问类型要么是public的,要么是没有修饰符的。如果一个类实现多个接口,这些接口被逗号分隔。如果一个类实现两个声明了同样方法的接口,那么相同的方法将被其中任一个接口客户使用。实现接口的方法必须声明成public。而且,实现方法的类型必须严格与接口定义中指定的类型相匹配。

  就想你可以想象到的一样,类可以使用接口,只是不用extends,而用implements(实现)

  下面是以iShape2D接口来实现CCircle类的范例:

class CCircle implements iShape2D  // 实现CCircle类

{

   double radius;

   public CCircle(double r){

      radius=r;

   }

   public void area(){    // 定义area()的处理方式

      System.out.println("area="+pi*radius*radius);     

   }

}

注意:当实现一个接口方法时,它必须声明成public

  有了上面的理论基础后,我们就可以开始编写程序代码了。exa4_19是以iShape2D接口实现CCircle与Crectangle两个类的范例:

例4-19

// exa4_19, 接口的实现范例

interface iShape2D   //定义接口

{

   final double pi=3.14;

   abstract void area();

}

 

class CRectangle implements iShape2D    // 实现CRectangle类

{

   int width,height;

   public CRectangle(int w,int h){

      width=w;

      height=h;

   }

   public void area(){   // 定义area()的处理方式

      System.out.println("area="+width*height);     

   }

}

 

class CCircle implements iShape2D  // 实现CCircle类

{

   double radius;

   public CCircle(double r){

      radius=r;

   }

   public void area(){    // 定义area()的处理方式

      System.out.println("area="+pi*radius*radius);     

   }

}

 

public class exa4_19

{

   public static void main(String args[])

   {

      CRectangle rect=new CRectangle(5,10); 

      rect.area();   //调用CRectangle类里的area() method

     

      CCircle cir=new CCircle(2.0); 

      cir.area();     // 调用CCircl类里的area() method

   }

}

  由本范例的程序代码可以看出,通过接口以及接口的实现在一起的类,我们可以编写出更简洁的程序代码。

  前已述及,我们不能直接由接口来创建对象,而必须通过由接口实现的类来创建。虽然如此,我们还是可以声明界面类型的变量(数组),并用它来访问对象。例4_20是利用这个思路写的,其中iShape2D接口、CCircleCrectangle类的定义均与例4-19相同,故将它们在例4-20中略去,因为在同一目录中,运行不会出现问题。

例4-20

// exa4_20.java, 通过接口类型的变量来访问对象

class exa4_20

{

   public static void main(String args[])

   {

      iShape2D var1,var2;  // 声明接口类型的变量

      var1=new CRectangle(5,10);  // 将接口类型的变量var1指向新建的对象

      var1.area();   // 通过接口var1调用area() method

     

      var2=new CCircle(2.0);  // 将接口类型的变量var2指向新建的对象

      var2.area();   // 通过接口var2调用area() method

   }

}

 

4-21,用一个类实现多个接口

 

//exa4_21.java

interface InterfaceExample1

{

       int i=4;

       void func1();

}

interface InterfaceExample2

{

       int k=5;

       void func2();

}

class Class3

{

       public void func2()

       {

              System.out.println("func2 in class3");

       }

}

public class exa4_21 extends Class3 implements InterfaceExample1,InterfaceExample2

       int j;

       public void func1()

       {

              System.out.println("func1 in exa4_21");

       }

       /*

       public void func2()

       {

              System.out.println("func2 in exa4_21");

       }

       */

       public static void main(String[] args)

       {

              exa4_21 c=new exa4_21();

           c.func1();

           c.func2();

       }

}

 

  程序中,exa4_21继承了Class3类和两个接口,那么必须把类写在前面,接口写在后面,接口之间用逗号分开,另外注意,由于Class3类实现了func2方法,因此在exa4_21中可以不再实现(当然也可以实现)

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值