2017.8.20學(xué)習(xí)小結(jié) - 類的封裝、繼承與多態(tài)2

回顧

一、面向?qū)ο蟮娜筇攸c(diǎn)

1.封裝的含義

2.繼承的含義

3.多態(tài)的含義

二、封裝的實(shí)現(xiàn)

1.Java訪問(wèn)權(quán)限修飾符

學(xué)習(xí)小結(jié)

2.封裝問(wèn)題引例

package com.Javastudy2;

/**
 * @author Y.W.
 * @date 2017年8月20日 上午10:49:26
 * @Description TODO 類的封裝性使用引例
 */
public class P281_12_1 {

    public static void main(String[] args) {
        MyCat aCat = new MyCat();
        aCat.weight = -10.0f; // 設(shè)置MyCat的屬性值
        float temp = aCat.weight; // 獲取MyCat的屬性值
        System.out.println("The weight of a cat is:" + temp);
    }

}

class MyCat{
    public float weight; // 通過(guò)public修飾符,開放MyCat的屬性給外界
    MyCat(){} // 無(wú)參構(gòu)造方法,無(wú)實(shí)際含義
}

運(yùn)行結(jié)果:

不現(xiàn)實(shí)的結(jié)果

引例把屬性(數(shù)據(jù))暴露出來(lái),讓外界可以任意接觸甚至改變它。運(yùn)行結(jié)果對(duì)于程序是沒(méi)有錯(cuò)誤的,賦值是合法的單精度浮點(diǎn)數(shù),但是現(xiàn)實(shí)中不可能有重量為負(fù)數(shù)的貓。

3.類的封裝實(shí)例

package com.Javastudy2;

/**
 * @author Y.W.
 * @date 2017年8月20日 上午11:04:25
 * @Description TODO 類的封裝實(shí)例
 */
public class P282_12_2 {

    public static void main(String[] args) {
        MyCat2 aCat = new MyCat2();
        aCat.weight = -10.0f; // 設(shè)置MyCat的屬性值
        float temp = aCat.weight; // 獲取MyCat的屬性值
        System.out.println("The weight of a cat is:" + temp);
    }

}

class MyCat2 {
    private float weight; // 通過(guò)private修飾符,封裝屬性
    MyCat2() {} // 無(wú)參構(gòu)造方法,無(wú)實(shí)際含義
}

運(yùn)行結(jié)果:

IDE報(bào)錯(cuò)/編譯報(bào)錯(cuò)

可以看到IDE已經(jīng)有報(bào)錯(cuò)了,編譯后同樣有報(bào)錯(cuò)信息。封裝后,外界無(wú)法訪問(wèn)私有屬性,若需要給這些屬性賦值,就需要存取屬性的公共接口。

package com.Javastudy2;

/**
 * @author Y.W.
 * @date 2017年8月20日 上午11:15:40
 * @Description TODO 類私有屬性的Setter和Getter方法
 */
public class P283_12_3 {

    public static void main(String[] args) {
        MyCat3 aCat = new MyCat3();
        aCat.SetWeight(-10f); // 設(shè)置MyCat的屬性值
        float temp = aCat.GetWeight(); // 獲取MyCat的屬性值
        System.out.println("The weight of a cat is:" + temp);
    }

}

class MyCat3 {
    private float weight; // 通過(guò)private修飾符,封裝MyCat的屬性

    public void SetWeight(float wt) {
        if (wt > 0) {
            weight = wt;
        } else {
            System.out.println("weight設(shè)置非法(應(yīng)該>0)。\n 采用默認(rèn)值");
            weight = 10.0f;
        }
    }

    public float GetWeight() {
        return weight;
    }
}

運(yùn)行結(jié)果:

運(yùn)行結(jié)果

通常,對(duì)屬性設(shè)置的方法被命名為SetXxx(),其中Xxx為任意有意義的名稱,這類方法可被統(tǒng)稱為Setter方法,而對(duì)屬性設(shè)置的方法被命名為GetYyy(),其中Xxx為任意有意義的名稱,這類方法可被統(tǒng)稱為Getter方法

注:見得多的還是setXxx()和getYyy()名稱。

封裝屬性:

private 屬性類型 屬性名;

封裝方法:

private 方法返回類型 方法名稱(參數(shù));

package com.Javastudy2;

/**
 * @author Y.W.
 * @date 2017年8月20日 上午11:40:55
 * @Description TODO 方法的封裝使用
 */
public class P284_12_4 {

    public static void main(String[] args) {
        MyCat4 aCat = new MyCat4();
        aCat.SetWeight(-10f); // 設(shè)置MyCat的屬性值
        float temp = aCat.GetWeight(); // 獲取MyCat的屬性值
        System.out.println("The weight of a cat is:" + temp);
        aCat.MakeSound(); // 會(huì)報(bào)錯(cuò)
    }

}

class MyCat4 {
    private float weight; // 通過(guò)private修飾符,封裝MyCat的屬性

    public void SetWeight(float wt) {
        if (wt > 0) {
            weight = wt;
        } else {
            System.out.println("weight設(shè)置非法(應(yīng)該>0)。\n 采用默認(rèn)值");
            weight = 10.0f;
        }
    }

    public float GetWeight() {
        return weight;
    }

    private void MakeSound() {
        System.out.println("Meow meow, my weight is " + weight);
    }
}

運(yùn)行結(jié)果:

IDE報(bào)錯(cuò)/編譯報(bào)錯(cuò)

封裝的MakeSound() 是無(wú)法外部調(diào)用的。

若類中某些數(shù)據(jù)在初始化時(shí)不想再被外界修改,則可以使用構(gòu)造方法配合私有化的Setter函數(shù)來(lái)實(shí)現(xiàn)該數(shù)據(jù)的封裝,如下例所示。

package com.Javastudy2;

/**
 * @author Y.W.
 * @date 2017年8月20日 上午11:52:43
 * @Description TODO 使用構(gòu)造方法實(shí)現(xiàn)數(shù)據(jù)的封裝
 */
public class P286_12_5 {

    public static void main(String[] args) {
        MyCat5 aCat = new MyCat5(12, -5); // 通過(guò)公有接口設(shè)置屬性值

        float ht = aCat.GetHeight(); // 通過(guò)公有接口獲取屬性值height
        float wt = aCat.GetWeight(); // 通過(guò)公有接口獲取屬性值weight
        System.out.println("The height of cat is " + ht);
        System.out.println("The weight of cat is " + wt);
    }

}

class MyCat5 {
    // 創(chuàng)建私有化屬性weight,height
    private float weight;
    private float height;

    // 在構(gòu)造方法中初始化私有變量
    public MyCat5(float height, float weight) {
        SetHeight(height); // 調(diào)用私有方法設(shè)置height
        SetWeight(weight); // 調(diào)用私有方法設(shè)置weight
    }

    // 通過(guò)private修飾符,封裝MyCat的SetWeight方法
    private void SetWeight(float wt) {
        if (wt > 0) {
            weight = wt;
        } else {
            System.out.println("weight設(shè)置非法(應(yīng)該>0)。\n 采用默認(rèn)值10");
            weight = 10.0f;
        }
    }

    // 通過(guò)private修飾符,封裝MyCat的SetHeight方法
    private void SetHeight(float ht) {
        if (ht > 0) {
            height = ht;
        } else {
            System.out.println("height設(shè)置非法(應(yīng)該>0)。\n 采用默認(rèn)值20");
            height = 20.0f;
        }
    }

    // 創(chuàng)建公有方法GetWeight()作為與外界的通信接口
    public float GetWeight() {
        return weight;
    }

    // 創(chuàng)建公有方法GetHeight()作為與外界的通信接口
    public float GetHeight() {
        return height;
    }
}

運(yùn)行結(jié)果:

運(yùn)行結(jié)果

4.封裝問(wèn)題的總結(jié)

在Java中,最基本的封裝單元是類,類是基于面向?qū)ο笏枷刖幊陶Z(yǔ)言的基礎(chǔ),程序員可以把具有相同業(yè)務(wù)性質(zhì)的代碼封裝在一個(gè)類里,通過(guò)接口方法向外部提供服務(wù),同時(shí)向外部代碼屏蔽類里的服務(wù)的具體實(shí)現(xiàn)方法。

數(shù)據(jù)封裝的最重要的目的是在于實(shí)現(xiàn)“信息隱藏(Information Hidding)”。

封裝性是面向?qū)ο蟪绦蛟O(shè)計(jì)的原則之一,使程序達(dá)到強(qiáng)內(nèi)聚(許多功能盡量在類的內(nèi)部獨(dú)立完成,不讓外界干預(yù)),弱耦合(提供給外部盡量少的方法調(diào)用)的最終目標(biāo)。

5.實(shí)現(xiàn)封裝應(yīng)該注意的問(wèn)題

封裝的數(shù)據(jù)是引用數(shù)據(jù)時(shí),如下例。

package com.Javastudy2;

import java.util.ArrayList;

/**
 * @author Y.W.
 * @date 2017年8月20日 下午12:59:40
 * @Description TODO 返回引用數(shù)據(jù)時(shí)應(yīng)該注意的問(wèn)題
 */
public class P288_12_6 {

    public static void main(String[] args) {
        TestReturn testReturn = new TestReturn();
        // 得到該私有數(shù)據(jù),不是副本,而是引用
        ArrayList<Integer> intArray = testReturn.getIntArray();
        System.out.println(intArray.size());

        intArray.add(4); // 修改其值

        ArrayList<Integer> intArray2 = testReturn.getIntArray();
        // 該類內(nèi)部的私有變量已經(jīng)被改變
        System.out.println("在外部修改其私有變量以后其長(zhǎng)度為:" + intArray2.size());
    }

}

class TestReturn {
    // 定義一個(gè)私有的ArrayList
    private ArrayList<Integer> intArray = new ArrayList<Integer>();

    public TestReturn() {
        // 通過(guò)構(gòu)造方法對(duì)其進(jìn)行初始化
        intArray.add(1);
        intArray.add(2);
        intArray.add(3);
    }

    // 設(shè)置私有數(shù)據(jù)對(duì)應(yīng)的get函數(shù)
    ArrayList<Integer> getIntArray() {
        return intArray;
    }
}

運(yùn)行結(jié)果:

運(yùn)行結(jié)果

封裝的變量被改變了。

解決辦法:

如果返回值是對(duì)數(shù)據(jù)的引用則顯示創(chuàng)建該數(shù)據(jù)的副本,然后返回該副本。

三、繼承的實(shí)現(xiàn)

1.繼承的基本概念

Java支持單繼承多層繼承,但不支持多繼承。

格式:

class 子類名 extends 父類

語(yǔ)法:

class 父類{
  // 定義父類
}
class 子類 extends 父類{
  // 用extends關(guān)鍵字實(shí)現(xiàn)類的繼承
}

Java只繼承父類的公有屬性和公有方法,以及隱含(不可見)的私有屬性。

2.繼承問(wèn)題的引出

package com.Javastudy2;

/**
 * @author Y.W.
 * @date 2017年8月20日 下午2:28:12
 * @Description TODO 繼承的引出
 */
public class P291_12_7 {

    public static void main(String[] args) {
        // 實(shí)例化一個(gè)Person對(duì)象
        Person11 person = new Person11("張三", 21);
        person.speak();
        // 實(shí)例化一個(gè)Student對(duì)象
        Student student = new Student("李四", 20, "HAUT");
        student.speak();
        student.study();
    }

}

class Person11 {
    String name;
    int age;

    Person11(String name, int age) {
        this.age = age;
        this.name = name;
    }

    void speak() {
        System.out.println("我的名字叫:" + name + "我" + age + "歲");
    }
}

class Student {
    String name;
    int age;
    String school;

    Student(String name, int age, String school) {
        this.age = age;
        this.name = name;
        this.school = school;
    }

    void speak() {
        System.out.println("我的名字叫:" + name + "我" + age + "歲");
    }

    void study() {
        System.out.println("我在" + school + "讀書");
    }
}

運(yùn)行結(jié)果:

運(yùn)行結(jié)果

3.實(shí)現(xiàn)繼承

上例代碼略顯臃腫,可以改造。

package com.Javastudy2;

/**
 * @author Y.W.
 * @date 2017年8月20日 下午2:50:21
 * @Description TODO 實(shí)現(xiàn)繼承
 */
public class P293_12_8 {
    public static void main(String[] args) {
        // 實(shí)例化一個(gè)Student對(duì)象
        Student1 s = new Student1("張三", 25, "工業(yè)大學(xué)");
        s.speak();
        s.study();
    }
}

class Person12 {
    String name;
    int age;

    Person12(String name, int age) {
        this.age = age;
        this.name = name;
    }

    void speak() {
        System.out.println("我的名字叫:" + name + "我" + age + "歲");
    }
}

class Student1 extends Person12 { // 繼承Person12
    String school;

    Student1(String name, int age, String school) {
        super(name, age);
        this.school = school;
    }

    void study() {
        System.out.println("我在" + school + "讀書");
    }
}

運(yùn)行結(jié)果:

運(yùn)行結(jié)果

4.繼承的限制

限制1

Java中不允許多重繼承,但是可以使用多層繼承。

多重繼承,指一個(gè)類同時(shí)繼承多個(gè)父類的行為和特征功能。

class A{
}
class B{
}
class C extends A,B{ // 錯(cuò)誤:多重繼承
}

多層繼承:指一個(gè)類B可以繼承來(lái)自類A,而另一個(gè)類C又繼承自B,像這樣在繼承層上單項(xiàng)繼承多個(gè)類。

class A{
}
class B extends A{
}
class C extends B{
}

注:編寫代碼時(shí),多層繼承最好不要超過(guò)三層。

限制2

從父類繼承的私有成員,不能被子類直接使用。

限制3

子類在進(jìn)行對(duì)象實(shí)例化時(shí),從父類繼承而來(lái)的數(shù)據(jù)成員需要先調(diào)用父類的構(gòu)造方法來(lái)初始化,然后再用子類的構(gòu)造方法來(lái)初始化本地的數(shù)據(jù)成員。

限制4

被final修飾的類不能再被繼承。

final在Java之中稱為終結(jié)器。

package com.Javastudy2;

/**
 * @author Y.W.
 * @date 2017年8月20日 下午3:33:43
 * @Description TODO 繼承的final限制
 */
public class P296_12_9 {
    public static void main(String[] args) {
        SubClass subClass = new SubClass();
    }
}

// 定義被final修飾的父類
final class SuperClass {
    String name;
    int age;
}

// 子類SubClass繼承SuperClass
class SubClass extends SuperClass {
    // do something
}
IDE報(bào)錯(cuò)/編譯報(bào)錯(cuò)

思考

一下看了好幾頁(yè),絕對(duì)超出我的臨時(shí)緩存了,腦瓜子有點(diǎn)疼。繼承性還要繼續(xù)加強(qiáng)。


記于2017年8月20日

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 34,687評(píng)論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,554評(píng)論 19 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,029評(píng)論 25 709
  • 一 十年風(fēng)雨總相隨。夢(mèng)里常思我是誰(shuí)? 今日重談人世事,幾多歡笑幾多悲? ...
    柳四公子閱讀 406評(píng)論 2 2
  • 每月最后一個(gè)星期天的散文沙龍是邯鄲這個(gè)中國(guó)散文之城散文人的重要聚會(huì)。今天的活動(dòng)選擇在新世紀(jì)八樓的石簡(jiǎn)書店。...
    東方飛鷹閱讀 684評(píng)論 0 1

友情鏈接更多精彩內(nèi)容