接口
接口是對類的一組需求的描述,這些類需要遵從接口描述的統一格式進行定義。
接口是一系列方法的聲明,是一些方法特徵的集合,一個接口只有方法的特徵沒有方法的實現,因此這些方法可以在不同的地方被不同的類實現,而這些實現可以具有不同的行爲。
作用:如果某個類實現了某個接口,那麼這個類就可以提供接口所描述的服務。
好處:Java不支持類多繼承(多繼承會讓語言本身變得非常複雜,效率也會降低)。在Java中每個類只能拓展與一個類,但是可以實現多個接口。接口可以提供多重繼承的大多數好處,同時還能避免多重繼承的複雜性和低效性。
接口的定義
java使用關鍵字interface來定義一個接口
格式 :
[修飾符] interface 接口名
{
[public] [static] [final] 常量;
[public] [abstract] 方法;
}
特點
- 接口中所有的方法自動屬於public,因此可以省略。
- 接口中不能包含實例域或靜態方法,但可以包含常量。接口中的域會被自動設爲public static final。
注:接口中還可以有靜態方法和默認方法。這是在 java SE 8之後引進的。
//聲明一個公共類型的接口
interface Animalable
{
int legs=4;
void eatFood();
//等價於下面
//public static final int legs=4;
//public abstract void eatFood();
}
接口的實現
接口定義中的抽象方法應該由使用該接口的類去實現(本質上是覆蓋方法)。
格式:
[修飾符] class 類名 implements 接口列表 //多個接口之間用逗號隔開
{
//實例域
//成員方法
//接口的實現
}
class Cat implements Animalable
{
private int age;
public Cat(int age)
{
this.age=age;
}
public int getAge()
{
return age;
}
//void eatFood() //error:Cat中的eatFood()無法實現Animalable中的eatFood(),正在嘗試分配更低的訪問權限:以前爲public
public void eatFood() //實現接口Animalable中的eatFood方法
{
System.out.println("貓吃老鼠");
}
}
接口的繼承:接口可以實現多繼承。
格式:
[修飾符] interface 接口名 extends 父類接口列表{
[public] [static] [final] 常量;
[public] [abstract] 方法;
}
interface A
{
int a=0;
int sum();
}
interface B extends A
{
int b=1;
void showB();
}
interface C extends A,B //如果一個接口繼承多個父接口,則父接口之間用逗號隔開
{
int c=3;
void showC();
}
class D implements C
{
public int sum()
{
return a+b+c;
}
public void showB()
{
System.out.println("b="+b);
}
public void showC()
{
System.out.println("c="+c);
}
}
class InterfanceTest
{
public static void main(String[] args)
{
D d=new D();
System.out.println("a="+d.a+",b="+d.b+",c="+d.c+",a+b+c="+d.sum());
d.showB();
d.showC();
}
}
運行結果
爲什麼接口可以實現多繼承而類不可以實現多繼承呢?
假設類可以實現多繼承
類A:有方法int sum(int a,int b){...}
類B:有方法int sum(int a,int b){...}
類C繼承了類A和類B。那麼,類C具有類A的sum方法,同時也有類B的sum方法。如果調用C的sum方法,系統不知道應該調用A類的sum()方法還是B類的sum()方法。
但是當使用接口時,
接口A:有方法int sum(int a,int b);
接口B:有方法int sum(int a,int b);
接口中的所有方法都是抽象的,sum方法的具體實現是由實現接口的類去實現的,不可能存在歧義。所有Java允許接口多繼承。
實例:對象數組排序(實現Comparable接口)
Arrays 類中sort方法可以對實現 Comparable 接口的類的對象進行排序。
Arrays.sort(Object[] a):根據元素的自然順序對指定對象數組進行升序排序
Comparable接口: 該接口對實現它的每個類對象強加一個整體排序。這個排序被稱爲類的自然排序,類的compareTo方法被稱爲其自然比較方法。
interface Comparable
{
int compareTo(Object o);
/* 自然比較方法
作用:比較此對象與指定對象的順序.如果該對象小於、等於或者大於指定對象,則分別返回負整數、零或正整數。
*/
}
現在Comparable接口已經改進爲泛型接口
interface Comparable<T>
{
int compareTo(T o);
}
import java.util.Arrays;
class Student implements Comparable
{
private String name;
private int no; //學號
private int age; //年齡
public Student(){
}
public Student(int no,int age,String name)
{
this.no=no;
this.age=age;
this.name=name;
}
public String toString()
{
return "學號:"+no+",名字:"+name+",年齡:"+age;
}
//對Comparable接口中的所有方法進行定義
public int compareTo(Object o)
{
Student other=(Student)o;
return this.no-other.no;
}
}
public class InterfaceDemo
{
public static void main(String[] args)
{
Student[] s=new Student[4];
s[0]=new Student(3,14,"張三");
s[1]=new Student(2,15,"李四");
s[2]=new Student(4,22,"王五");
s[3]=new Student(1,18,"葉葉");
System.out.println("-----排序前--------");
for(Student temp:s)
{
System.out.println(temp.toString());
}
Arrays.sort(s);
System.out.println("-----排序後--------");
for(Student temp:s)
{
System.out.println(temp.toString());
}
}
}
Student類 實現泛型接口
public class Student implements Comparable<Student>
{
//Comparable泛型接口的實現
public int compareTo(Student o)
{
return this.no-o.no;
}
}
運行結果
接口實現多態
interface Animalable
{
int age=0;
public void eat();
}
class Cat implements Animalable
{
public int age=4;
public void eat()
{
System.out.println("貓吃老鼠");
}
public void playGame()
{
System.out.println("貓喜歡玩毛線球");
}
}
class Dog implements Animalable
{
public int age=3;
public void eat()
{
System.out.println("狗啃骨頭");
}
}
class Pig implements Animalable
{
public void eat()
{
System.out.println("豬吃白菜");
}
}
class DuoTai3
{
public static void main(String[] args)
{
Animalable s=new Dog();
System.out.println(s.age); //調用的是接口的常量
s.eat();
System.out.println("-------------");
s=new Pig();
System.out.println(s.age); //調用的是接口的常量
s.eat();
System.out.println("-------------");
s=new Cat();
System.out.println(s.age); //調用的是接口的常量
s.eat();
System.out.println("-------------");
if(s instanceof Cat)
{
Cat d=(Cat)s;
System.out.println(d.age);
d.eat();
d.playGame();
}
}
}
運行結果