1. 程式人生 > >java面向物件【重寫、this、super,抽象類】

java面向物件【重寫、this、super,抽象類】

第1章    繼承

1.1    繼承中方法重寫&應用

l  子父類成員方法特殊情況——覆蓋

子類中出現與父類一模一樣的方法時,會出現覆蓋操作,也稱為override重寫、複寫或者覆蓋。

class Fu

{

    public void show()

{

System.out.println("Fushow");

}

}

class Zi extends Fu

{

    //子類複寫了父類的show方法

publicvoid show()

{

System.out.println("Zishow");

}

}

l  方法重寫(覆蓋)的應用:

當子類需要父類的功能,而功能主體子類有自己特有內容時,可以重寫父類中的方法,這樣,即沿襲了父類的功能,又定義了子類特有的內容。

舉例:比如手機,當描述一個手機時,它具有發簡訊,打電話,顯示來電號碼功能,後期由於手機需要在來電顯示功能中增加顯示姓名和頭像,這時可以重新定義一個類描述智慧手機,並繼承原有描述手機的類。並在新定義的類中覆蓋來電顯示功能,在其中增加顯示姓名和頭像功能。

在子類中,訪問父類中的成員方法格式:

super.父類中的成員方法();

看如下程式碼:

public class Test {

    publicstatic void main(String[] args) {

        newNewPhone().showNum();

    }

}

//手機類

class Phone{

    publicvoid sendMessage(){

        System.out.println("發簡訊");

    }

    publicvoid call(){

        System.out.println("打電話");

    }

    public void showNum(){

        System.out.println("來電顯示號碼");

    }

}

//智慧手機類

class NewPhone extends Phone{

    //覆蓋父類的來電顯示號碼功能,並增加自己的顯示姓名和圖片功能

    public void showNum(){

        //呼叫父類已經存在的功能使用super

        super.showNum();

        //增加自己特有顯示姓名和圖片功能

        System.out.println("顯示來電姓名");

        System.out.println("顯示頭像");

    }

}

1.2    方法重寫的注意事項

重寫需要注意的細節問題:

l  子類方法覆蓋父類方法,必須要保證許可權大於等於父類許可權。

class Fu(){

void show(){}

    publicvoid method(){}

}

class Zi() extends Fu{

public void show(){}  //編譯執行沒問題

    voidmethod(){}      //編譯錯誤

}

l  寫法上稍微注意:必須一模一樣:函式的返回值型別 函式名 引數列表都要一樣。

總結:當一個類是另一個類中的一種時,可以通過繼承,來繼承屬性與功能。如果父類具備的功能內容需要子類特殊定義時,進行方法重寫。

1.3    繼承中子類中出現與父類重名的成員變數

當子父類中出現了同名成員變數時,在子類中若要訪問父類中的成員變數,必須使用關鍵字super來完成。

在子類中,訪問父類中的成員變數格式:

super.父類中的成員變數

看如下程式碼:

class Fu

{

    //Fu中的成員變數。

    int num = 5;

}

class Zi extends Fu

{

    //Zi中的成員變數

    int num = 6;

    voidshow()

    {

        //子父類中出現了同名的成員變數時

        //在子類中需要訪問父類中非私有成員變數時,需要使用super關鍵字

        //訪問父類中的num

        System.out.println("Funum="+super.num);

        //訪問子類中的num2

        System.out.println("Zinum2="+this.num);

    }

}

class Demo5

{

    publicstatic void main(String[] args)

    {

        Zi z =new Zi(); //建立子類物件

        z.show();//呼叫子類中的show方法

    }

}

1.4    this與super

1.4.1   父類物件空間優於子類物件產生

在每次建立子類物件時,我們均會先建立父類物件,再建立其子類物件本身。目的在於子類物件中包含了其對應的父類物件空間,便可以包含其父類物件的成員,如果父類成員非private修飾,則子類可以隨意使用父類成員。

程式碼體現在子類的構造方法呼叫時,一定先呼叫父類的構造方法。

1.4.2   繼承關係圖(this與super)

當子類建立物件後,該子類物件本身可以使用this來指代,而該物件當中的父類物件空間可以使用super來指代。

如下為加入了子父類關係後的物件記憶體圖。

以Person類為例:

    //定義父類

    public classPerson {

        privateString name;

        privateint age;

        publicPerson(){}

        publicPerson(String name,int age) {

            this.name= name;

            this.age= age;

         }

        //get/set方法

     }

//定義子類

public class Chinese extends Person{

    privateString address;

    publicChinese(){}

    publicChinese(String name,int age,String address) {

        super(name,age);

        this.address= address;

}

//對address的get/set


    //定義測試類,使用子類建立物件

public class Test{

    Chinese c= new Chinese(“AngelaBaby”,18,”北京海淀區上地軟體園”);

}


1.1.1   this與super呼叫普通成員與構造方法

l 呼叫普通成員:

this.成員變數       可以訪問本類物件的成員變數

super.成員變數     可以訪問父類物件的成員變數

this.成員方法()     可以訪問本類物件的成員方法

super.成員方法()    可以訪問父類物件的成員方法

l 呼叫構造方法:

this(其他引數)      可以訪問本類其他的構造方法

super(其他引數)    可以訪問父類其他的構造方法

l 預設子類呼叫父類構造方法

子類的每個構造方法中均有預設的super(),呼叫父類的空參構造。手動呼叫父類構造會覆蓋預設的super();

第2章    抽象類

2.1    抽象類-產生

當編寫一個類時,我們往往會為該類定義一些方法,這些方法是用來描述該類的功能具體實現方式,那麼這些方法都有具體的方法體。

但是有的時候,某個父類只是知道子類應該包含怎麼樣的方法,但是無法準確知道子類如何實現這些方法。比如一個圖形類應該有一個求周長的方法,但是不同的圖形求周長的演算法不一樣。那該怎麼辦呢?

分析事物時,發現了共性內容,就出現向上抽取。會有這樣一種特殊情況,就是方法功能宣告相同,但方法功能主體不同。那麼這時也可以抽取,但只抽取方法宣告,不抽取方法主體。那麼此方法就是一個抽象方法。

         如:

描述講師的行為:工作。

描述助教的行為:工作。

描述班主任的行為:工作。

講師、助教、班主任之間有共性,可以進行向上抽取。抽取它們的所屬共性型別:員工。由於講師、助教、班主任都具有工作功能,但是他們具體工作內容卻不一樣。這時在描述員工時,發現了有些功能不能夠具體描述,那麼,這些不具體的功能,需要在類中標識出來,通過java中的關鍵字abstract(抽象)修飾。

當定義了抽象函式的類也必須被abstract關鍵字修飾,被abstract關鍵字修飾的類是抽象類。

2.2    抽象類&抽象方法的定義

抽象方法定義的格式:

public abstract 返回值型別方法名(引數);

抽象類定義的格式:

abstract class 類名 {

}

看如下程式碼:

//員工

abstractclass Employee{

publicabstractvoid work();//抽象函式。需要abstract修飾,並分號;結束

}

//講師

class TeacherextendsEmployee {

publicvoid work() {

System.out.println("正在講解Java");

}

}

//助教

class AssistantextendsEmployee {

publicvoid work() {

System.out.println("正在輔導學生");

}

}

//班主任

class ManagerextendsEmployee {

publicvoid work() {

System.out.println("正在管理班級");

}

}

2.3    抽象類&抽象方法的使用

抽象類無法直接建立物件,只能被子類繼承後,建立子類物件

子類需要繼承抽象父類並完成最終的方法實現細節(即重寫方法,完成方法體)。而此時,方法重寫不再是加強父類方法功能,而是父類沒有具體實現,子類完成了具體實現,我們將這種方法重寫也叫做實現方法。

抽象類是擁有構造方法的,其存在的意義在於對自身進行初始化,供其子類使用。

2.4    抽象類常見疑惑

l  抽象類一定是個父類,因為抽象類時不斷抽取共性需求而來的。

l  抽象類中是可以不定義抽象方法的,此時僅僅是不讓該類建立物件,用於某些特殊的設計需要。

l 設計時由具體類抽取出抽象類,而開發階段應該先定義抽象父類,再根據不同需求由父類定義子類。

第3章   綜合案例---員工類系列定義

3.1    案例介紹

某IT公司有多名員工,按照員工負責的工作不同,進行了部門的劃分(研發部員工、維護部員工)。研發部根據所需研發的內容不同,又分為JavaEE工程師、Android工程師;維護部根據所需維護的內容不同,又分為網路維護工程師、硬體維護工程師。

公司的每名員工都有他們自己的員工編號、姓名,並要做它們所負責的工作。

l  工作內容

n  JavaEE工程師:員工號為xxx的xxx員工,正在研發淘寶網站

n  Android工程師:員工號為xxx的xxx員工,正在研發淘寶手機客戶端軟體

n  網路維護工程師:員工號為xxx的 xxx員工,正在檢查網路是否暢通

n  硬體維護工程師:員工號為xxx的 xxx員工,正在修復印表機

請根據描述,完成員工體系中所有類的定義,並指定類之間的繼承關係。進行XX工程師類的物件建立,完成工作方法的呼叫。

3.2    案例分析

l  根據上述部門的描述,得出如下的員工體系圖

l  根據員工資訊的描述,確定每個員工都有員工編號、姓名、要進行工作。則,把這些共同的屬性與功能抽取到父類中(員工類),關於工作的內容由具體的工程師來進行指定。

n  工作內容

u  JavaEE工程師:員工號為xxx的 xxx員工,正在研發淘寶網站

u  Android工程師:員工號為xxx的xxx員工,正在研發淘寶手機客戶端軟體

u  網路維護工程師:員工號為xxx的 xxx員工,正在檢查網路是否暢通

u  硬體維護工程師:員工號為xxx的 xxx員工,正在修復印表機

l  建立JavaEE工程師物件,完成工作方法的呼叫

1.1    案例程式碼實現

l  根據員工體系圖,完成類的定義

定義員工類(抽象類)

publicabstractclass Employee {

    private Stringid;// 員工編號

    private Stringname;// 員工姓名

    public String getId() {

returnid;

    }

    publicvoidsetId(String id) {

        this.id =id;

    }

    public String getName() {

returnname;

    }

    publicvoidsetName(String name) {

        this.name =name;

    }

//工作方法(抽象方法)

publicabstractvoid work();

}

l  定義研發部員工類Developer 繼承 員工類Employee

publicabstractclass DeveloperextendsEmployee {

}

l  定義維護部員工類Maintainer 繼承 員工類Employee

publicabstractclass MaintainerextendsEmployee {

}

l  定義JavaEE工程師 繼承 研發部員工類,重寫工作方法

publicclass JavaEEextendsDeveloper {

@Override

publicvoid work() {

System.out.println("員工號為 " +getId() + " " + getName() +"員工,正在研發淘寶網站");

}

}

l  定義Android工程師 繼承 研發部員工類,重寫工作方法

publicclass AndroidextendsDeveloper {

@Override

publicvoid work() {

System.out.println("員工號為 " +getId() + " " + getName() +"員工,正在研發淘寶手機客戶端軟體");

}

}

l  定義Network網路維護工程師 繼承 維護部員工類,重寫工作方法

publicclass NetworkextendsMaintainer {

@Override

publicvoid work() {

System.out.println("員工號為 " +getId() + " " + getName() +"員工,正在檢查網路是否暢通");

}

}

l  定義Hardware硬體維護工程師 繼承 維護部員工類,重寫工作方法

publicclass HardwareextendsMaintainer {

@Override

publicvoid work() {

System.out.println("員工號為 " +getId() + " " + getName() +"員工,正在修復印表機");

}

}

l  在測試類中,建立JavaEE工程師物件,完成工作方法的呼叫

publicclass Test {

    publicstaticvoid main(String[]args) {

//建立JavaEE工程師員工物件

        JavaEEee =newJavaEE();

//設定該員工的編號

        ee.setId("000015");

//設定該員工的姓名

        ee.setName("小明");

//呼叫該員工的工作方法

        ee.work();

    }

}