1. 程式人生 > 其它 >介面與內部類

介面與內部類

技術標籤:java

飛機、鳥和超人不能歸於一個類屬,但是具備有相同的特性:會飛的。所以引入了一個新概念叫做介面,可以用於
規範實現介面的類中必須實現介面中抽象方法。介面可以理解為一種契約
使用關鍵字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("我對準..."
); } }

在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 = "yanjun";// 介面中只能定義常量,不能定義屬性,預設限定詞public static
final,自定義限定詞不能衝突
}
class B implements IA{} //訪問常量既可以通過介面IA和實現類B名稱的方式直接訪問,例如
B.name。也可以通過B物件的方式進行訪,例如new B().name

介面允許多重繼承,也允許一個類實現多個介面

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();
}
}

介面允許多重繼承

interface IA1{
public void p1();
}
interface IA2{
public void p2();
}
interface IC extends IA1,IA2{
public void p3(); //繼承父介面的同時也允許自定義方法
}//可以繼承多個父介面,此時IC中實際有3個抽象方法

類是單根繼承,不允許繼承多個父類
允許一個類實現多個介面,但是每個介面的抽象方法都必須提供實現,否則是抽象類。提供的實現也可以是繼承

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()

如果定義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();

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();
}
}

介面和抽象類的異同點
相同點:都是不斷向上抽取而來的
不同點:
抽象類需要被繼承,而且只能單繼承
介面需要被實現,而且可以多實現
抽象類中可以定義抽象方法和非抽象方法,子類繼承後可以直接使用非抽象方法
介面中只能定義抽象方法,必須由子類去實現;JDK1.8+中允許介面中的方法有預設實現,實現類中可以直接
使用預設實現,允許覆蓋定義
抽象類的繼承是is a關係,在定義該體系的基本共性內容
介面的實現是like a關係,在定義體系額外功能
介面中只能定義常量,而且必須被初始化,抽象類中可以定義屬性,允許在宣告時直接初始化,也可以不初
始化,同時允許定義常量