Java中物件導向三大特性之繼承

蝴蝶飛啊飛發表於2019-10-17

1. 繼承的概述

繼承就是子類繼承父類的變數和方法,下面用程式碼解釋一下:

class Student {// 定義學生類

String name;

int age;

void study() {

System.out.println(name + "studay good" + age);

}

}

class Work {// 定義工人類

String name;

int age;

void work() {

System.out.println(name + "work good" + age);

}

}

從上述例子中可以看到,學生類和工人類都有共同的特徵,為了實現程式碼複用性,進行抽取,java 中抽取用類表示將共有的的行為或特徵進行抽取,然後原來的來類也要可以用,我們就需要用原來類繼承我們抽取的類,用 extends 關鍵字進行呼叫,如:

class Student extends Person {// 定義學生類

void study() {

System.out.println(name + "studay good" + age);

}

}

class Work extends Person {// 定義工人類

void work() {

System.out.println(name + "work good" + age);

}

}

class Person {// 定義我們抽取的類

String name;

int age;

}

通常稱Person (被繼承的類)類為父類(也叫操類,基類),稱 Work Student (繼承類)稱為子類。

2. 繼承的優點

提高程式碼複用性

讓類與類產生關係,給多型提供了前提

java 支援單繼承,不支援多繼承,對 C++ 多繼承進行改良

單繼承:一個子類只能有一個直接父類

class A {

}

class B {

}

class C extends A {

}

或者

class A {

}

class B {

}

class C extends B {

}

多繼承:一個子類能有多個直接父類( 為什麼不能多繼承 ) 【不直接支援,會產生呼叫的不確定性】

class A {

void show() {

System.out.println(a);

}

}

class B {

void show() {

System.out.println(b);

}

}

class C extends A,B {

}

當我們new c(); 呼叫 show 方法,呼叫的是 A 的還是 B 的?為了區分 java 對此進行了改良,不用多繼承,用介面

java 支援多層(多重繼承) => 傳遞性

class A {

}

class B extends A {

}

class C extends B {

}

3. 類的繼承原則

單繼承

繼承具有傳遞性

繼承不能迴圈

Object 類,所有類都有父類

4. 繼承的使用

當要使用一個繼承體系時,如何使用 ?

檢視該體系中頂層類,瞭解該體系的基本功能。

建立該體系中最子類的外匯返傭http://www.kaifx.cn/物件,完成功能的使用。

什麼時候寫繼承?

當類存在所屬關係,就定義繼承,A 屬於 B, A 繼承 B

5. 繼承中的成員變數

當本類區域性和成員變數名相同時用this 區分

當子父類中成員變數相同時用super 區分

this super 的用法很相似

this :代表一個本類物件的引用

super :代表一個父類空間

class A {

int num = 5;

}

class B extends A {

int num = 10;

void show() {

System.out.println(this.num + " …… " + super.num);// 呼叫子類和父類的成員變數

}

}

注意:子類不能直接訪問父類的私有成員

6. 繼承中的成員方法

class A {

int num = 5;

void show1() {

System.out.println(num);

}

}

class B extends A {

int num = 10;

void show2() {

System.out.println(num);

}

}

public class Extendstext {

public static void main(String[] args) {

B b = new B();

b.show1();

b.show2();

}

}

當子父類中函式一樣,將會執行子類的函式,稱為覆蓋操作

class A {

int num = 5;

void show() {

System.out.println(num);

}

}

class B extends A {

int num = 10;

void show() {

System.out.println(num);

}

}

public class Extendstext {

public static void main(String[] args) {

B b = new B();

b.show();

}

}

6.1 函式的兩個特性

過載:同一個類

覆蓋:子類中,覆蓋也叫重寫

6.2 注意事項

子類的方法覆蓋父類方法時,子類的許可權必須大於父類的許可權

靜態只能覆蓋靜態,或被靜態覆蓋

6.3 什麼時候使用覆蓋操作

當對一個類進行子類擴充套件時,子類需要保留父類的功能宣告,但要定義子類能的特有內容時,就用覆蓋操作完成。( 修改方法,新增功能 ) 如:

class Phone {// 定義一個手機類

void call() {// 通話功能

}

void show() {// 展示功能

System.out.println("number");

}

}

class newphone extends Phone {

void show() {// 展示功能重寫

System.out.println("name");

System.out.println("jpg");

System.out.println("number");

}

}

或者

class newphone extends Phone {

void show() {// 展示功能重寫

System.out.println("name");

System.out.println("jpg");

super.show();// 呼叫父類 show 方法

}

}

7. 繼承中的建構函式

在子類構造物件時,訪問子類建構函式時,父類也執行,在子類的建構函式中,有一個預設的隱士語句,super(); 呼叫父類中空引數的建構函式,無覆蓋,無繼承

無引數

class fu {

fu() {

System.out.println("fu run");

}

}

class zi extends fu {

zi() {

super();// 隱士自帶的呼叫父類空引數建構函式

System.out.println("zi run");

}

}

有引數

class fu {

fu(int x) {

System.out.println("fu run");

}

}

class zi extends fu {

zi() {

super(4);// 隱士自帶的呼叫父類空引數建構函式

System.out.println("zi run");

}

}

子類的例項化過程,子類中的每個建構函式都會訪問父類中空引數的建構函式

結果:AC AD

public class Extendstext {

public static void main(String[] args) {

new zi();

new zi(6);

}

}

class fu {

fu(){

System.out.println("A");

}

fu(int x) {

System.out.println("B");

}

}

class zi extends fu {

zi() {

System.out.println("C");

}

zi(int x){

System.out.println("D");

}

}

結果:BD

public class Extendstext {

public static void main(String[] args) {

new zi(6);

}

}

class fu {

fu(){

System.out.println("A");

}

fu(int x) {

System.out.println("B");

}

}

class zi extends fu {

zi() {

System.out.println("C");

}

zi(int x){

super(x);// 覆蓋隱式 super();

System.out.println("D");

}

}

繼承的優勢

提高程式碼的複用性,更簡潔。

關於繼承的記憶體結構 :(程式碼如下)

// 子類

package com.ss.cn;

/*

 * 物件導向 -- 繼承

 * 要建立倆個老師的類 java php 老師

 *   老師有什麼屬性 :name age

 *   老師的行為  : teach  sleep 休息

 *

 */

public class JavaTeacher extends Teacher {

    // 利用封裝的方式

    /*private String name;

    private int age;*/

    // 方法 :

    public void teach() {

        /*

         * 就是說的當前那麼不是子類中的 name ,不是本類的東西那是絕對訪問不了

         * name 現在在父類中, private String name 私有的受保護的,就是說其他類要是訪問不了的,即使他有繼承的關係

         *

         */

        System.out.println(getName()+" 在教課 ");

    }

    // 為什麼要 setget 方法

    /*

     * 利用封裝時要想取得到值 也必須需要生成 set/get 方法

     * 生成 set/get 方法快捷鍵 : shift+alt+s

     */

}

// 子類 :

package com.ss.cn;

/*

 * 物件導向 -- 繼承

 * 要建立倆個老師的類 java php 老師

 *   老師有什麼屬性 :name age

 *   老師的行為  : teach  sleep 休息

 *   建立老師的父類

 *   繼承的語法 :關鍵字 extends

 *    class 子類 extends 父類 {

 *       子類的屬性;

 *       子類的方法;

 *    }

 *     特點 : 子類會把福父類的所有屬性和方法繼承下來(出來 final

 */

public class HtmlTeacher extends Teacher{

    public void teach() {

        System.out.println(getName()+" 在教 html ");

    }

}

package com.ss.cn;

// 父類

public class Teacher {

    // 公共類

    private  String name;

    private  int age;

    public void sleep() {

        System.out.println(name+" 在睡覺 ");

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public int getAge() {

        return age;

    }

    public void setAge(int age) {

        this.age = age;

    }

}

// 測試類

package com.ss.cn;

public class ExtendsDemo {

    public static void main(String[] args) {

        // TODO Auto-generated method stub

        //1. 物件中的屬性就必須建立物件

        JavaTeacher jTeacher=new JavaTeacher();

        jTeacher.setName("Mrs");

        jTeacher.setAge(25);

        jTeacher.teach();

        // 同理 :

        HtmlTeacher hTeacher=new HtmlTeacher();

        hTeacher.setName("ssy");

        hTeacher.setAge(23);

        hTeacher.sleep();

        hTeacher.teach();

    }

}

為什麼自子類例項化的時候,會呼叫父類構造方法?

子類繼承父類,所以子類有父類的屬性,在使用父類內容前,要先看父類如何對自己的內容進行初始化,所以子類建構函式初始化的時候,必須呼叫父類建構函式,所以在子類的建構函式預設加了super();

如果父類中沒有定義無參建構函式或者說是父類中定義了有參,沒有定義無參,那麼必須用super(); 來指定呼叫父類的建構函式

如果子類的建構函式中使用了this(); 呼叫本類的建構函式,那麼 super(); 就沒有了,因為 super this 只能定義在第一行,所以只能有一個,但是可以保證的是,子類中肯定會有其他構造方法來訪問父類的建構函式。

注意:super(); 語句必須要定義在子類建構函式的第一行,因為父類的初始化要先完成


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69946279/viewspace-2660338/,如需轉載,請註明出處,否則將追究法律責任。

相關文章