Java 抽象類與接口的使用

抽象類的定義與使用

抽象類的概念:
抽象類就是在普通類的基礎上擴充一些抽象方法,所謂的抽象方法指的是值聲明而未實現的方法(沒有方法體)
所有的抽象方法要求使用abstract關鍵字來定義,並且抽象等待所在的類也一定要用abstract關鍵字定義,表示抽象類
 

abstract class Person{//定義一個抽象類
    private String name;//屬性

    public String getName() {//普通方法
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    //{}裏面的代碼爲方法體,所有抽象方法不包含方法體
    public abstract void getPerson();//抽象方法
}

抽象類中包含抽象方法,而抽象方法不包含方法體,即沒有具體實現因此抽象類不能夠產生實例化對象

對於抽象類的使用原則
a.所有的抽象類必須有子類
b.抽象類的子類必須覆寫抽象類的所有抽象方法
c.抽象類的對象可以通過對象多態性利用子類爲其實例化
d.private 與 abstract 不能同時使用

abstract class Person{
    private String name;//屬性

    public String getName() {//普通方法
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    //{}裏面的代碼爲方法體,所有抽象方法不包含方法體
    public abstract void getPerson();//抽象方法
}

class Student extends Person{
    @Override
    public void getPerson() {//覆寫父類方法
        System.out.println("我是子類覆寫後的對象");
    }
}
public class Test{
    public static void main(String[] args){
        Person per = new Student();
        per.getPerson();//調用子類覆寫的方法
    }
}

抽象類的相關規定
1、在抽象類中允許提供構造方法,並且子類遵循對象實例化對象。實例化子類時必須先調用父類構造方法

abstract class Person{
    private String name;//屬性
    public Person(){//構造方法
        System.out.println("Person類的構造方法");
    }

    public String getName() {//普通方法
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public abstract void getInfo();//抽象方法
}
class Student extends Person{

    public Student() {
        super();//如果父類沒有無參構造必須super指出調用的具體父類構造方法
        System.out.println("Student類的構造方法");
    }

    @Override
    public void getInfo() { }//子類覆寫方法空實現
}
public class Test{
    public static void main(String[] args){
        new Student();//Person類的構造方法
                      // Student類的構造方法
    }
}

對象實例化操作的核心步驟:
類加載 -> 類對象的開闢 -> 類對象屬性的初始化(構造方法)

2、抽象類中允許不定義抽象方法,但是此時抽象方法仍然無法直接創建實例化對象

abstract class Person{
    public void print(){
        System.out.println("Person類的普通方法");
    }
}

public class Test{
    public static void main(String[] args){
        Person per = new Person();//會報錯,Person類是抽象的,無法實例化
    }
}

3、抽象類一定不能使用final聲明,因爲final聲明的類不允許有子類,抽象類又必須有子類;抽象方法也不能用private定義,因爲抽象方法必須被覆寫

4、抽象類分爲內部抽象類和外部抽象類。內部抽象類中可以使用static定義來描述外部抽象類

abstract class Person{
    public abstract void print();//外部類抽象方法
    static abstract class Student{
        public abstract void print2();//內部類抽象方法
    }
}
class Child extends Person{
    @Override
    public void print() {
    }
    class A extends Student{
        @Override
        public void print2() {
        }
    }
}

接口的定義與使用
抽象類與普通類相比最大的特點就是約定了子類的實現要求,但是抽象類存在單繼承侷限,如果要約定子類的實現要求且避免單繼承就可以使用接口

接口的基本概念
定義:接口就是一個抽象方法和全局常量的集合,用interface關鍵字定義

interface Imes{
    public static final String MSG = "這是一個全局常量";
    public abstract void print();//抽象方法
}

子類要想實現接口,就必須使用implements關鍵字來實現接口。
同時,一個子類可以實現多個接口,對於接口的子類必須覆寫接口的全部抽象方法,隨後利用子類的向上轉型通過實例化子類得到接口的實例化對象

子類實現接口 & 父接口相互轉換

interface Imes{
    public static final String MSG = "這是一個全局常量";
    public abstract void print();//抽象方法
}
interface INew{
    public abstract String getNews();
}
class Mess implements Imes,INew {
    @Override
    public void print() {
        System.out.println(Imes.MSG);
    }
    @Override
    public String getNews() {
        return Imes.MSG;
    }
}
public class Test{
    public static void main(String[] args){
       Imes m = new Mess();//子類實現向上轉型
	   //真正new的子類纔有意義
        m.print();//調用被子類覆寫過的方法
        INew n = (INew) m;
        System.out.println(n.getNews());
    }
}

接口使用限制
接口只允許使用public權限(不管是屬性還是方法,其權限都是public)

接口的兩種定義

//完整格式:
interface Imes{
    public static final String MSG = "這是一個全局常量";
    public abstract void print();
}
//簡化格式:
interface Imes{
    final String MSG = "這是一個全局常量";
    void print();
}

阿里編碼規約:接口中的方法和屬性不加任何修飾符號,public也不要加,保持代碼的簡潔性

當一個子類即需要實現接口又需要繼承類時,需先使用extends繼承一個抽象類,而後使用implements實現多個接口

//子類繼承抽象類和實現接口
abstract class News{
    //抽象類中方法前面的abstract不能省略,否則就是普通方法
    public abstract void getNews();
}
class Message extends News implements Imes{
    @Override
    public void print() {
        System.out.println("我覆寫了接口方法");
    }
    @Override
    public void getNews() {
        System.out.println("我覆寫了抽象方法");
    }
}

public class Test{
    public static void main(String[] args){
        //Message是抽象類與接口的共同子類
        Imes m = new Message();
        m.print();
        News news = (News) m;
        news.getNews();
    }
}

一個抽象類可以使用implements實現多個接口

interface Imes{
    void print();
}

abstract class News implements Imes{
    //抽象類中方法前面的abstract不能省略,否則就是普通方法
    public abstract void getNews();
}
class Message extends News{
    @Override
    public void print() {
        System.out.println("我實現了接口方法");
    }
    @Override
    public void getNews() {
        System.out.println("我實現了抽象方法");
    }
}

此關係屬於三層繼承
class Message extends News implements Imes

一個接口可以使用extends繼承多個父接口

interface A{
    void printA();
}
interface B{
    void printB();
}
interface C extends A,B{
    void printC();
}
class Impl implements C{

    @Override
    public void printA() { }

    @Override
    public void printB() { }

    @Override
    public void printC() { }
}

接口可以定義一系列的內部結構,包括:內部普通類、內部接口。其中使用static定義的內部接口就相當於一個外部接口

//使用static定義的內部接口
interface A{
    void printA();
    static interface B{
        void printB();
    }
}
class Impl implements A.B {
    @Override
    public void printB() { }
}

接口能力的應用:定義標準
接口在實際開發中有三大核心應用環境
a.定義操作標準
b.表示能力
c.在分佈式開發之中暴露遠程服務方法
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章