JavaSE基礎之面向對象和封裝(六)

文章目錄

(一)面向對象思想的概述
(二)面向對象思想的舉例
(三)類和對象的關係
(四)類的定義
(五)對象的創建及其使用
(六)練習:定義一個手機類
(七)一個對象的內存圖
(八)兩個對象使用同一個方法的內存圖
(九)兩個引用指向同一個對象的內存圖
(十)使用對象類型作爲方法的參數
(十一)使用對象類型作爲方法的返回值
(十二)成員變量和局部變量的區別
(十三)面向對象三大特徵之封裝性
(十四)private關鍵字的作用及使用
(十五)練習:使用private關鍵字定義學生類
(十六)this關鍵字的作用
(十七)構造方法
(十八)定義一個標準的類

(一)面向對象思想的概述

  • 面向過程:當需要實現一個功能的時候,每一個具體的步驟都要親力親爲,詳細處理每一個細節
  • 面向對象:當需要實現一個功能的時候,不關心具體的步驟,而是找一個已經具有該功能的人來幫我做事兒

面向對象思想是一種更符合我們思考習慣的思想,它可以將複雜的事情簡單化,並將我們從執行者變成了指揮者

面向對象的語言中,包含了三大基本特徵,即封裝繼承多態

(二)面向對象思想的舉例

public class Demo01PrintArray {

    public static void main(String[] args) {
        int[] array = { 10, 20, 30, 40, 50, 60 };

        // 要求打印格式爲:[10, 20, 30, 40, 50]
        // 使用面向過程,每一個步驟細節都要親力親爲。
        System.out.print("[");
        for (int i = 0; i < array.length; i++) {
            if (i == array.length - 1) { // 如果是最後一個元素
                System.out.println(array[i] + "]");
            } else { // 如果不是最後一個元素
                System.out.print(array[i] + ", ");
            }
        }
        System.out.println("==============");

        // 使用面向對象
        // 找一個JDK給我們提供好的Arrays類,
        // 其中有一個toString方法,直接就能把數組變成想要的格式的字符串
        System.out.println(Arrays.toString(array));
    }

}

(三)類和對象的關係

:是一組相關屬性和行爲的集合。
可以看成是一類事物的模板,使用事物的屬性特徵和行爲特徵來描述該類事物
屬性:就是該事物的狀態信息
行爲:就是該事物能夠做什麼

舉例:小貓
屬性:名字、體重、年齡、顏色
行爲:走、跑、叫

對象:是一類事物的具體體現
對象是類的一個實例,必然具備該類事物的屬性行爲

舉例:一隻小貓
屬性:tom、5kg、2 years、yellow
行爲:溜牆根走、蹦躂的跑、喵喵叫

類與對象的關係

  • 類是對一類事物的描述,是抽象的
  • 對象是一類事物的實例,是具體的
  • 類是對象的模板,對象是類的實體

(四)類的定義

  • 現實世界的一類事物:
    屬性:事物的狀態信息
    行爲:事物能夠做什麼
  • Java中用class描述事物也是如此:
    成員變量:對應事物的屬性
    成員方法:對應事物的行爲
public class Student {
	//成員變量
	String name;//姓名
	int age;//年齡
	//成員方法
	//學習的方法
	publicvoid study() {
	System.out.println("好好學習,天天向上");
	} /
	/喫飯的方法
	publicvoid eat() {
	System.out.println("學習餓了要喫飯");
	}
}

(五)對象的創建及其使用

創建對象:類名 對象名 = new 類名();
使用對象訪問類中的成員:對象名.成員變量;對象名.成員方法();
在這裏插入圖片描述

(六)練習:定義一個手機類

Phone.java:

public class Phone {

    // 成員變量
    String brand; // 品牌
    double price; // 價格
    String color; // 顏色

    // 成員方法
    public void call(String who) {
        System.out.println("給" + who + "打電話");
    }

    public void sendMessage() {
        System.out.println("羣發短信");
    }
}

Demo01PhoneOne.java:

public class Demo01PhoneOne {

    public static void main(String[] args) {
        // 根據Phone類,創建一個名爲one的對象
        // 格式:類名稱 對象名 = new 類名稱();
        Phone one = new Phone();
        System.out.println(one.brand); // null
        System.out.println(one.price); // 0.0
        System.out.println(one.color); // null
        System.out.println("=========");

        one.brand = "蘋果";
        one.price = 8388.0;
        one.color = "黑色";
        System.out.println(one.brand); // 蘋果
        System.out.println(one.price); // 8388.0
        System.out.println(one.color); // 黑色
        System.out.println("=========");

        one.call("喬布斯"); // 給喬布斯打電話
        one.sendMessage(); // 羣發短信
    }

}

(七)一個對象的內存圖

首先把.class相關的放入方法區,如下:
在這裏插入圖片描述
接着main方法入棧,如下:
在這裏插入圖片描述
開始逐行運行main方法,首先在中創建一個Phone對象,如下:
注意:對於堆中的對象,每一個對象的成員變量可以是不同的,但是他們的成員方法是一樣的,所以它們只需要存成員方法的內存地址即可
在這裏插入圖片描述
對於創建完對象後執行的三條打印語句就不展示了,下面展示改變對象屬性的值,如下:
注意:通過one,找到one對應的堆內存地址,然後就可以修改了
在這裏插入圖片描述
接着執行成員方法,如下:
注意:通過one找到堆內存的地址,再在堆中找到方法對應的方法區內存地址
注意:入棧之所以也被稱爲壓棧,是因爲先進後出,新入棧就好像是壓進去的一樣
在這裏插入圖片描述
方法執行完就要出棧,也被稱爲彈棧,如下:
在這裏插入圖片描述
call()方法被銷燬後,main()方法重見天日,繼續執行下一個方法,如下:
在這裏插入圖片描述
執行完之後同樣會被銷燬(出棧),如下:
在這裏插入圖片描述
最後main()方法也被銷燬,如下:
在這裏插入圖片描述
至此,程序執行完畢

(八)兩個對象使用同一個方法的內存圖

首先依然是.class相關的信息進入方法區,接着main()方法入棧,接着在中創建第一個對象,如下:
在這裏插入圖片描述
然後方法入棧之後出棧,這裏不一一展示了,如下:
在這裏插入圖片描述
接着在堆中創建第二個對象,如下:
注意:它們都是指向同一個方法區中的方法
在這裏插入圖片描述
執行第二個對象相關的方法,如下:
在這裏插入圖片描述
最後main()方法也被銷燬,如下:
在這裏插入圖片描述
至此,程序執行完畢

(九)兩個引用指向同一個對象的內存圖

兩個對象引用指向同一個對象空間
在這裏插入圖片描述

(十)使用對象類型作爲方法的參數

先把.class相關的信息存入方法區,main方法入棧,在堆中創建對象,如下:
在這裏插入圖片描述
method(one)方法首先拿到0x666地址值,再把該地址值傳遞(賦值)給param,從而調用相關方法
注意:當一個對象作爲參數,傳遞到方法當中時,實際上傳遞進去的是對象的地址值
在這裏插入圖片描述
方法執行完被銷燬就不畫圖了,跟之前差不多

(十一)使用對象類型作爲方法的返回值

注意:當使用一個對象類型作爲方法返回值時,返回值其實就是對象的地址值
在這裏插入圖片描述
方法執行完被銷燬就不畫圖了,跟之前差不多

(十二)成員變量和局部變量的區別

在這裏插入圖片描述
定義的位置不一樣【重點】

  • 局部變量:在方法的內部
  • 成員變量:在方法的外部,直接寫在類當中

作用範圍不一樣【重點】

  • 局部變量:只有方法當中纔可以使用,出了方法就不能再用
  • 成員變量:整個類全都可以通用

默認值不一樣【重點】

  • 局部變量:沒有默認值,如果要想使用,必須手動進行賦值
  • 成員變量:如果沒有賦值,會有默認值,規則和數組一樣

內存的位置不一樣(瞭解)

  • 局部變量:位於棧內存
  • 成員變量:位於堆內存

生命週期不一樣(瞭解)

  • 局部變量:隨着方法進棧而誕生,隨着方法出棧而消失
  • 成員變量:隨着對象創建而誕生,隨着對象被垃圾回收而消失
public class Demo01VariableDifference {

    String name; // 成員變量

    public void methodA() {
        int num = 20; // 局部變量
        System.out.println(num);
        System.out.println(name);
    }

    public void methodB(int param) { // 方法的參數就是局部變量
        // 參數在方法調用的時候,必然會被賦值的。
        System.out.println(param);

        int age; // 局部變量
//        System.out.println(age); // 沒賦值不能用

//        System.out.println(num); // 錯誤寫法!
        System.out.println(name);
    }

}

(十三)面向對象三大特徵之封裝性

面向對象三大特徵:封裝繼承多態

封裝性在Java當中的體現:

  1. 方法就是一種封裝
  2. 關鍵字private也是一種封裝(後面會介紹)

封裝就是將一些細節信息隱藏起來,對於外界不可見

public class Demo02Method {

    public static void main(String[] args) {
        int[] array = {5, 15, 25, 20, 100};

        int max = getMax(array);
        System.out.println("最大值:" + max);
    }

    // 給我一個數組,我還給你一個最大值
    public static int getMax(int[] array) {
        int max = array[0];
        for (int i = 1; i < array.length; i++) {
            if (array[i] > max) {
                max = array[i];
            }
        }
        return max;
    }

}

(十四)private關鍵字的作用及使用

問題描述:定義Person的年齡時,無法阻止不合理的數值被設置進來
解決方案:用private關鍵字將需要保護的成員變量進行修飾

一旦使用了private進行修飾,那麼本類當中仍然可以隨意訪問
但是!超出了本類範圍之外就不能再直接訪問了

間接訪問private成員變量,就是定義一對兒Getter/Setter方法

必須叫setXxx或者是getXxx命名規則
對於Getter來說,不能有參數,返回值類型和成員變量對應
對於Setter來說,不能有返回值,參數類型和成員變量對應

public class Person {

    String name; // 姓名
    private int age; // 年齡

    public void show() {
        System.out.println("我叫:" + name + ",年齡:" + age);
    }

    // 這個成員方法,專門用於向age設置數據
    public void setAge(int num) {
        if (num < 100 && num >= 9) { // 如果是合理情況
            age = num;
        } else {
            System.out.println("數據不合理!");
        }
    }

    // 這個成員方法,專門私語獲取age的數據
    public int getAge() {
        return age;
    }

}
public class Demo03Person {

    public static void main(String[] args) {
        Person person = new Person();
        person.show();

        person.name = "趙麗穎";
//        person.age = -20; // 直接訪問private內容,錯誤寫法!
        person.setAge(20);
        person.show();
    }

}

(十五)練習:使用private關鍵字定義學生類

對於基本類型當中的boolean值,Getter方法一定要寫成isXxx的形式,而setXxx規則不變

public class Student {

    private String name; // 姓名
    private int age; // 年齡
    private boolean male; // 是不是爺們兒

    public void setMale(boolean b) {
        male = b;
    }

    public boolean isMale() {
        return male;
    }

    public void setName(String str) {
        name = str;
    }

    public String getName() {
        return name;
    }

    public void setAge(int num) {
        age = num;
    }

    public int getAge() {
        return age;
    }
}
public class Demo04Student {

    public static void main(String[] args) {
        Student stu = new Student();

        stu.setName("鹿晗");
        stu.setAge(20);
        stu.setMale(true);

        System.out.println("姓名:" + stu.getName());
        System.out.println("年齡:" + stu.getAge());
        System.out.println("是不是爺們兒:" + stu.isMale());
    }

}

(十六)this關鍵字的作用

當方法的局部變量和類的成員變量重名的時候,根據“就近原則”,優先使用局部變量
如果需要訪問本類當中的成員變量,需要使用格式:this.成員變量名

public class Person {

    String name; // 我自己的名字

    // 參數name是對方的名字
    // 成員變量name是自己的名字
    public void sayHello(String name) {
        System.out.println(name + ",你好。我是" + this.name);
        System.out.println(this);
    }

}
public class Demo01Person {

    public static void main(String[] args) {
        Person person = new Person();
        // 設置我自己的名字
        person.name = "王健林";
        person.sayHello("王思聰"); //王思聰,你好。我是王健林

        System.out.println(person); // 地址值
    }

}

(十七)構造方法

構造方法是專門用來創建對象的方法,當我們通過關鍵字new來創建對象時,其實就是在調用構造方法
格式

public 類名稱(參數類型 參數名稱) {
    方法體
}

注意事項:

  1. 構造方法的名稱必須和所在的類名稱完全一樣,就連大小寫也要一樣
  2. 構造方法不要寫返回值類型,連void都不寫
  3. 構造方法不能return一個具體的返回值
  4. 如果沒有編寫任何構造方法,那麼編譯器將會默認贈送一個構造方法,沒有參數、方法體什麼事情都不做
  5. 一旦編寫了至少一個構造方法,那麼編譯器將不再贈送
  6. 構造方法也是可以進行重載的
    重載:方法名稱相同,參數列表不同
public class Student {

    // 成員變量
    private String name;
    private int age;

    // 無參數的構造方法
    public Student() {
        System.out.println("無參構造方法執行啦!");
    }

    // 全參數的構造方法
    public Student(String name, int age) {
        System.out.println("全參構造方法執行啦!");
        this.name = name;
        this.age = age;
    }

    // Getter Setter
    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }

}
public class Demo02Student {

    public static void main(String[] args) {
        Student stu1 = new Student(); // 無參構造
        System.out.println("============");

        Student stu2 = new Student("趙麗穎", 20); // 全參構造
        System.out.println("姓名:" + stu2.getName() + ",年齡:" + stu2.getAge());
        // 如果需要改變對象當中的成員變量數據內容,仍然還需要使用setXxx方法
        stu2.setAge(21); // 改變年齡
        System.out.println("姓名:" + stu2.getName() + ",年齡:" + stu2.getAge());

    }

}

(十八)定義一個標準的類

一個標準的類通常要擁有下面四個組成部分:

  1. 所有的成員變量都要使用private關鍵字修飾
  2. 爲每一個成員變量編寫一對兒Getter/Setter方法
  3. 編寫一個無參數的構造方法
  4. 編寫一個全參數的構造方法

這樣標準的類也叫做Java Bean

public class Student {

    private String name; // 姓名
    private int age; // 年齡

    public Student() {
    }

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

    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;
    }
}
public class Demo01Student {

    public static void main(String[] args) {
        Student stu1 = new Student();
        stu1.setName("迪麗熱巴");
        stu1.setAge(20);
        System.out.println("姓名:" + stu1.getName() + ",年齡:" + stu1.getAge());
        System.out.println("=================");

        Student stu2 = new Student("古力娜扎", 21);
        System.out.println("姓名:" + stu2.getName() + ",年齡:" + stu2.getAge());
        stu2.setAge(22);
        System.out.println("姓名:" + stu2.getName() + ",年齡:" + stu2.getAge());
    }

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