java基础知识之接口

来源:互联网 发布:炒股行情分析软件 编辑:程序博客网 时间:2024/05/23 22:18

一,  接口的定义与描述


1,接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过实现接口的方式,从而来实现接口的抽象方法。

2,java接口(Interface),是一系列方法的声明,是一些方法特征的集合,这些方法特征来自于具体方法,这些方法符合它们一般来自于一些在系统中不断出现的方法。一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为,也就是可以具有完全不同的功能

3,在人们讲到“接口”时,这个词往往有两种不同的含义:第一种是指Java接口,这是一种Java语言中存在的结构,有特定的语法和结构。第二种仅仅是指一个类所具有的方法的特征集合,是一种逻辑上的抽象。前者叫做“Java接口”,后者叫做“接口”。

4,接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。

5,接口把方法的特征和方法的实现分割开来。这种分割,体现在接口常常代表一个角色(role),它包装与该角色相关的操作和属性,而实现这个接口的类便扮演这个角色的演员(类)。一个角色(接口)可以由不同的演员(类)来演,而不同的演员(类)之间除了扮演一个共同的角色(接口)之外,并不要求有任何其他的共同之处。


二,  接口的种类


1, 单方法接口,

以下是引用片段:

public interface IPeople{

          public abstract void eat(String food);

}

有且只有一个方法,只有实现了这个接口(重写这个接口中的唯一一个方法),你才有资格去事件监听器列表里注册(参数为IPeople类型),当事件源变动时,自动调用这个唯一的eat方法。这种接口是最常用也是最普遍的接口。

2,标识接口

这种接口是一种没有任何方法和属性的接口。标识接口不对实现它的类有任何语意上的要求,它仅仅表明了实现它的类属于一个特定的类型(传递), 供其他代码来测试允许做一些事情。不推荐过多的使用标识接口。

标识接口作用:简单形象的说就是给某个对象打个标(盖个戳),使对象拥有某个或某些特权。

标识接口主要用于以下两种目的

(1)建立一个公共的父接口:正如EventListener接口,这是由几十个其他接口扩展的Java API,你可以使用一个标记接口来建立一组接口的父接口。例如:当一个接口继承了EventListener接口,Java虚拟机(JVM)就知道该接口将要被用于一个事件的代理方案。

(2)向一个类添加数据类型:这种情况是标记接口最初的目的,实现标记接口的类不需要定义任何接口方法(因为标记接口根本就没有方法),但是该类通过多态性变成一个接口类型。

3,常量接口

用Java接口来声明一些常量,然后由实现这个接口的类使用这些常量。

建议不要模仿这种常量接口的做法。


三,  接口的使用与注意点


1,接口文件创建规则如下:

  • 接口文件保存在 .java 结尾的文件中,文件名使用接口名。
  • 接口的字节码文件保存在 .class 结尾的文件中。
  • 接口相应的字节码文件必须在与包名称相匹配的目录结构中。

2,定义接口的基本格式如下:

[修饰符] interface [接口名]extends[父接口1,父接口2,...]

{

           [public] [static] [final] 常量;
           [public] [abstract] 方法;

}
修饰符:可选,用于指定接口的访问权限,可选值为public。如果省略则使用默认的访问权限,也是public的。
接口名:必选参数,用于指定接口的名称,接口名必须是合法的Java标识符。一般情况下,要求首字母大写,一般为了方便代码阅读,会在接口名前边加上大写字母“I”,以表示这个文件是个接口文件。

父接口名列表:可选参数,用于指定要定义的接口继承于哪个父接口。当使用extends关键字时,父接口名为必选参数。

常量:只能包含public,static,final类型的成员变量,这些成员变量必须被显式初始化,即接口中的成员变量为常量(大写,单词之间用"_"分隔)
方法:接口中的方法只有定义而没有被实现,也就是没有方法体,这些方法都会被隐式的指定为public abstract(只能是 public abstract,其他修饰符都会报错)

注意点:

  •  一个接口是可以使用extends关键字继承接口,并且可以继承多个接口,但是不能使用implements去实现接口。
  •  接口是隐式抽象的,当声明一个接口的时候,可以不必使用abstract关键字,修饰符public也可以省略不写
  •  一个接口可以有多个方法和常量。
  •  接口中是不能包含实例域或静态方法的。

3,接口的实现格式

接口在定义后,就可以在类中实现该接口。在类中实现接口可以使用关键字implements,其基本格式如下:
[修饰符]  class  [类名] implements[接口1,接口2,...]

{


}
修饰符:可选参数,用于指定类的访问权限,可选值为public、abstract和final。
类名:必选参数,用于指定类的名称,类名必须是合法的Java标识符。一般情况下,要求首字母大写。

接口列表:可选参数,用于指定该类实现的是哪些接口。当使用implements关键字时,接口列表为必选参数。当接口列表中存在多个接口名时,各个接口名之间使用逗号分隔。

 注意点:

  •  接口必须要有子类实现,一个子类可以使用implements关键字实现多个接口;
  •  当类实现了某个Java接口时,它必须实现接口中的所有抽象方法,否则这个类必须声明为抽象类,反过来说如果实现接口的类是抽象类,那么就没必要实现该接口的方法,也就是不需要重写该方法。
  •   接口的对象可以利用子类对象的向上转型进行实例化
  •   接口不是类,尤其不用使用new运算符实例一个接口,也就是说不能构造接口的对象,却能声明接口的变量。(出现在回调设计模式中,体现了Java的多态特性),该变量只能引用实现了接口的类对象。
  •   接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。
  •   类在重写接口方法时,方法的名字参数的个数类型必须与接口中的完全一致,返回值应该保持相同或者相兼容。
  •   类在实现接口的方法时,不能抛出强制性异常,只能在接口中,或者继承接口的抽象类中抛出该强制性异常。

4,同时继承抽象类和实现接口格式

对于子类而言,除了实现接口外,还可以继承抽象类。若既要继承抽象类,同时还要实现接口的话,使用以下语法格式:

[修饰符] class[子类]extends[抽象类]implements[接口1,接口2...] {

 

}

修饰符:可选参数,用于指定类的访问权限,可选值为public、abstract和final。
子类:必选参数,用于指定类的名称,类名必须是合法的Java标识符。一般情况下,要求首字母大写。
抽象类:可选参数,用于指定要定义的类继承于哪个父类。当使用extends关键字时,父类名为必选参数。

接口参数列表:可选参数,用于指定该类实现的是哪些接口。当使用implements关键字时,接口列表为必选参数。当接口列表中存在多个接口名时,各个接口名之间使用逗号分隔。


四,总结


(1)从接口的概念上来讲,接口只能由抽象方法和全局常量组成,但是内部结构是不受概念限制的,正如抽象类中可以定义抽象内部类一样,在接口中也可以定义普通内部类、抽象内部类和内部接口(但从实际的开发来讲,用户自己去定义内部抽象类或内部接口的时候是比较少见的)

(2)接口实现和类继承的规则不同,为了数据的安全,继承时一个类只有一个直接父类,也就是单继承,但是一个类可以实现多个接口,接口弥补了类的不能多继承缺点,继承和接口的双重设计既保持了类的数据安全也变相实现了多继承。

(3)接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

(4)Java接口本身没有任何实现,因为Java接口不涉及表象,而只描述public行为,所以Java接口比Java抽象类更抽象化。但是接口不是类,不能使用new 运算符实例化一个接口

如 x=new comparable(......);//这个是错误来的。但是可以声明接口变量Comparable x; //这是允许的。

(5)Java接口的方法只能是抽象的和公开的,Java接口不能有构造器,Java接口可以有public、静态的和final属性。即接口中的属性可以定义为 public static final int value=5;

(6)如果一个类已经有了一个主要的超类型,那么通过实现一个接口,这个类可以拥有另一个次要的超类型,这种次要的超类型叫做混合类型。

 

,举例说明


/**
 
* 申明接口人
 
* 默认规则会在接口名前边加大写字母“I”,以便于区分该文件为接口文件。
 */
//public abstract interface IPeople {//关键字
//abstract interface IPeople {
interface IPeople extends Eat,Sleep{//一个接口是可以使用extends关键字继承接口,并且可以继承多个接口
    //申明常量,可以有多个常量,成员常量具有固定的修饰符:public static final
    //public static final int data = 0;//public,static,final这三个修饰符都可以省略不写,
    int DATA= 0;//常量必须要显式初始化,否则会引起报错
   
public static final double NUM=0;
  
 //申明方法,可以有多个方法。
   
public abstract void drink(Stringfood);//public,abstract这两个修饰符都可以省略不写
    int singing();//方法禁止用static,final,private等修饰符修饰
}


 

//接口吃饭
public interface Eat{
   
/**
    
* 方法吃饭
    
* @param what 要吃的食物
    
*/
    public void eat(Stringwhat);

}


//接口睡觉
public interface Sleep{
   
/**
    
* 方法睡觉
    
* @param bed 睡在什么样的床上
    
*/
    public void sleep(Stringbed);

}

 /**
 
* 创建类XiaoCui实现IPeople接口
 */
//可以同时继承抽象类并且实现多个接口
public class XiaoCui  extends People implements IPeople,Sleep{
   
//如果一个类实现了接口中的方法,那么只实现一次就可以了。即使继承了两次接口
   
//一个子类可以使用implements关键字实现多个接口
    //必须要实现其中的两个抽象方法,否则会报错,除非将这个类申明为抽象类

    public void cry() {//可以拥有自己的方法
       
System.out.println("哭");
   
}
   
@Override
   
public void run(){//实现抽象类People中的抽象方法
        System.out.println("跑");
   
}
   
@Override
   
public void drink(String food) {//实现IPeople接口中的方法
        System.out.println("喝水");
   
}
   
@Override
   
public int singing() {//实现IPeople接口中的方法
        System.out.println("唱歌");
       
return 0;//类在重写接口方法时,方法的名字、参数的个数及类型必须与接口中的完全一致,返回值应该保持相同或者相兼容。
   
}
   
@Override
   
public void eat(String what) {//实现接口Eat中的方法,
                // 虽然这个类没有直接实现接口Eat,但是接口IPeople继承了接口Eat,所以必须要实现这个方法。
        System.out.println("吃饭");
   
}
   
//实现接口Sleep中的抽象方法
    @Override
   
public void sleep(String bed) {
       
System.out.println("睡觉");
   
}

   
publicstatic void main(String[]args){
       
XiaoCui  xiaocu i= new XiaoCui();//实例化子类对象
       
IPeople  people=xiaocui;//接口的对象可以利用子类对象的向上转型进行实例化。
       
Sleep sleep=xiaocui;//该变量只能引用实现了接口的类对象。
     
// Sleep sleep = new Sleep(); //接口不是类,尤其不用使用new运算符实例一个接口
        people.drink("hh");
       
people.singing();
       
sleep.sleep("dd");
   
}
}