# 最徹底的抽象類:接口
[TOC]
## 概述
如果在一個類中,一個實現的方法都沒有,或者都是抽象方法,那么,這樣的類,成為接口。
接口定義使用 `interface` 關鍵詞定義
語法:
~~~
[修飾符] interface 接口名 extends 父接口1, 父接口2... {
0-N 個常量;
0-N個抽象方法;
}
~~~
* 接口中所有的成員在定義的時候訪問控制修飾符只能是 public 或者是 default;
* 接口的命名規范同類的命名規范;
* 在接口中,成員變量必須是靜態的常量,方法必須是抽象方法,所以可以省略相關的修飾符。
## 接口的繼承
接口的繼承和類的繼承不一樣,接口支撐多繼承,使用 extends 關鍵字,之間用逗號隔開,繼承的內容包含了,常量和方法
Inter1.java
~~~
public interface Inter1 {
static final String C1 = "c1"; // 常量定義的命名規范是全部大寫,兩個單詞之間用 _
void Inter1fun1();
void Inter1fun2();
}
~~~
Inter2.java
~~~
public interface Inter2 {
static String C2 = "c2"; // 常量定義的命名規范是全部大寫,兩個單詞之間用 _
void Inter2fun1();
void Inter2fun2();
}
~~~
Inter3.java
~~~
public interface Inter3 extends Inter1, Inter2{
static String C3 = "c3"; // 常量定義的命名規范是全部大寫,兩個單詞之間用 _
void Inter3fun1();
void Inter3fun2();
}
~~~
InterImpl.java
~~~
public class InterImpl implements Inter3{
@Override
public void Inter1fun1() {
System.out.println("Inter1fun1");
}
@Override
public void Inter1fun2() {
System.out.println("Inter1fun2");
}
@Override
public void Inter2fun1() {
System.out.println("Inter2fun1");
}
@Override
public void Inter2fun2() {
System.out.println("Inter2fun2");
}
@Override
public void Inter3fun1() {
System.out.println("Inter3fun1");
}
@Override
public void Inter3fun2() {
System.out.println("Inter3fun2");
}
public static void main(String[] args) {
InterImpl ii = new InterImpl();
System.out.println(ii.C1);
System.out.println(ii.C2);
System.out.println(ii.C3);
ii.Inter1fun1();
ii.Inter2fun1();
ii.Inter2fun2();
ii.Inter1fun2();
ii.Inter3fun1();
ii.Inter3fun2();
}
}
~~~
InterImpl2.java
~~~
public class InterImpl2 implements Inter1, Inter2{
@Override
public void Inter2fun1() {
// TODO Auto-generated method stub
}
@Override
public void Inter2fun2() {
// TODO Auto-generated method stub
}
@Override
public void Inter1fun1() {
// TODO Auto-generated method stub
}
@Override
public void Inter1fun2() {
// TODO Auto-generated method stub
}
}
~~~
## 接口的使用
接口是抽象類一樣,是不能被實例化的,但是接口可以用于聲明引用類型的變量,當使用接口來聲明變量時,該變量的運行時類型必須是該接口的實現類。
接口的作用:
* 用于定義實現類的行為規范;
* 定義變量
* 定義一些常量
* 被其他類實現
一個類是可以實現多個接口的,使用 implements 關鍵字,多個接口之間用逗號隔開。
一個完整的類定義的語法:
> 在一個 java 文件中,是可以定義多個類的,但是只允許有一個 public 類型的類存在。定義的 public 類型的類必須和文件名一致。
~~~
[修飾符:public、final] class 類名 extends 父類 implements 接口1,接口2...{
....
}
~~~
## 接口和抽象類
**相同點:**
* 都不能被實例化,位于繼承樹的頂端,是用于被其他類繼承或者實現的;
* 都可以包含抽象方法,子類都必須要實現抽象方法;
在實際的開發中,都是接口先行,一般都是先定義接口,然后開發人員實現接口,完成具體方法的實現。
抽象類是個半成品,可以作為一個模板去使用。
**不同點:**
* 抽象類中可以定義普通方法,但是接口中都是抽象方法和靜態變量;
* 在抽象類是可以定義靜態方法的,接口中不能定義靜態方法的;
* 在抽象中可以定義構造器的,但是在接口中是不存在構造器這個概念的;
* 一個類最多只能有一個直接的父類或者抽象類,但是可以有多個接口的實現。
## 練習
**在設計LOL的時候,進攻類英雄有兩種,一種是進行物理系攻擊,一種是進行魔法系攻擊 這時候,就可以使用接口來實現這個效果。 接口就像是一種約定,我們約定某些英雄是物理系英雄,那么他們就一定能夠進行物理攻擊**
1. **設計物理攻擊接口**
2. **設計一類英雄,能夠使用物理攻擊**
3. **魔法攻擊接口**
4. **設計一類英雄,只能使用魔法攻擊**
5. **設計一類英雄,既能進行物理攻擊,又能進行魔法攻擊**
6. **設計輔助英雄接口**
~~~java
/**
* 英雄基類
* @author 一教室
*
*/
public class Hero {
public String name;
public int hp;//生命值
public int mp;//魔法值
public double speed;//移動速度
public int defense;//防御值
public int attackPower;//攻擊力
public Hero(String name, int hp, int mp, double speed, int defense, int attackPower) {
super();
this.name = name;
this.hp = hp;
this.mp = mp;
this.speed = speed;
this.defense = defense;
this.attackPower = attackPower;
}
public Hero() {
super();
}
}
/**
* 物理系攻擊接口
* @author 一教室
*
*/
public interface AD {
//物理傷害方法
public void physicalAttack();
}
/**
* 物理系英雄
* @author 一教室
*
*/
public class ADHero extends Hero implements AD {
@Override
public void physicalAttack() {
System.out.println("正在使用物理攻擊");
}
}
/**
* 魔法系攻擊接口
* @author 一教室
*
*/
public interface AP {
/**
* 魔法攻擊方法
*/
public void magicAttack();
}
public class APHero extends Hero implements AP {
@Override
public void magicAttack() {
System.out.println("正在進行魔法攻擊");
}
}
public class ADAPHero extends Hero implements AD, AP{
@Override
public void magicAttack() {
System.out.println("又進行魔法攻擊");
}
@Override
public void physicalAttack() {
System.out.println("又進行物理攻擊");
}
}
/**
* 輔助英雄接口
* @author 一教室
*
*/
public interface SUP {
public void support();
}
~~~