文章目錄
(一)面向對象思想的概述
(二)面向對象思想的舉例
(三)類和對象的關係
(四)類的定義
(五)對象的創建及其使用
(六)練習:定義一個手機類
(七)一個對象的內存圖
(八)兩個對象使用同一個方法的內存圖
(九)兩個引用指向同一個對象的內存圖
(十)使用對象類型作爲方法的參數
(十一)使用對象類型作爲方法的返回值
(十二)成員變量和局部變量的區別
(十三)面向對象三大特徵之封裝性
(十四)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當中的體現:
- 方法就是一種封裝
- 關鍵字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 類名稱(參數類型 參數名稱) {
方法體
}
注意事項:
- 構造方法的名稱必須和所在的類名稱完全一樣,就連大小寫也要一樣
- 構造方法不要寫返回值類型,連void都不寫
- 構造方法不能return一個具體的返回值
- 如果沒有編寫任何構造方法,那麼編譯器將會默認贈送一個構造方法,沒有參數、方法體什麼事情都不做
- 一旦編寫了至少一個構造方法,那麼編譯器將不再贈送
- 構造方法也是可以進行重載的
重載:方法名稱相同,參數列表不同
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());
}
}
(十八)定義一個標準的類
一個標準的類通常要擁有下面四個組成部分:
- 所有的成員變量都要使用private關鍵字修飾
- 爲每一個成員變量編寫一對兒Getter/Setter方法
- 編寫一個無參數的構造方法
- 編寫一個全參數的構造方法
這樣標準的類也叫做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());
}
}