# 面向對象編程
[TOC]
## 面向過程和面向對象編程
例如 C 語言、VB 語言都是面向過程的編程語言。通過一個函數(方法)解決一件事情,「就事論事」。事情處理完成后,是不會留下任何「遺產」的。
一件事情:
例如 「南通渡課 IT 教育 Java班同學在 1 教室上李老師的 Java 課」。
用面向對象的思維邏輯去分析,抽象實體:
* 班級
* 學生
* 教室
* 老師
* 課程
* 學校
通過類封裝實體的屬性和動作(方法)。
## 類與對象
**類**: 是一種自定義的數據類型。有時把這種數據類型也叫做「類類型」或者「引用數據類型」。「引用」就是內存地址的意思。
**對象**:通過類創建的變量,或者叫類的實體。
>[success] 類是一群對象的特征母版,對象是類的具體實例。
> 類是一群對象的抽象。
### 類的定義
>[warning] 類所具備的最基本要素:(靜態)屬性、(動態)方法。
語法:
~~~
[修飾符] class 類名 {
// 成員變量
[修飾符] 數據類型 成員變量1;
[修飾符] 數據類型 成員變量2;
...
// 方法
[修飾符] 返回值 方法名1([參數列表]) {
方法體語句;
}
[修飾符] 返回值 方法名2([參數列表]) {
方法體語句;
}
...
// 構造器:創建對象用的方法
[修飾符] 類名([參數列表1]) {
方法語句;
}
[修飾符] 類名([參數列表2]) {
方法語句;
}
}
~~~
### 類的三大組成部件
**類的三大部件:成員變量、方法、構造器。**
示例:
~~~
public class Student1 {
// 構造器
Student1(String name, int age, String code) {
this.name = name;
this.age = age;
this.code = code;
}
// 成員變量
String name;
int age;
String code;
// 方法
String intro() {
return "我叫"+this.name+",我的學號是"+this.code+",我今年"+this.age+"歲了。";
}
void listen() {
System.out.println(this.name + "在上課。");
}
}
~~~
### 使用類構建對象
~~~
public static void main(String[] args) {
// 構建一個對象:調用類的構造器
Student1 hehao = new Student1("何浩", 20, "C25");
// 用對象:給屬性賦值
hehao.birthday = new Date(); // 賦值
System.out.println(hehao.code); // 獲取屬性值
// 用對象:調用對象的方法
System.out.println(hehao.intro());
hehao.listen();
}
~~~
>[info] 類名的定義要符合 Java 的標識符命名規范,類名首字母大寫,如果多個單詞,使用駝峰命名法則(每個獨立單詞首字母大寫),**在 Java 中,只要看到首字母大寫,你就是一個類。**
> 類中三大部件的定義是沒有嚴格的順序的,但是,我們一般遵循,構造器、成員變量、方法這樣的定義順序。
## 構造器
語法:
~~~
[修飾符] 類名([參數列表]){}
~~~
* 構造器本身是一個比較特殊的方法,方法名就是類名,沒有返回值(和void是有區別的),構造器是類創建對象的唯一途徑。如果一個類沒有顯示的定義一個構造器,那么編譯器就會給這個類默認定義一個沒有參數的構造器。
* 如果顯示的定義了一個構造器,那么**編譯器就不會給這個類定義默認的構造器**
## 成員變量
語法:
~~~
[修飾符] 數據類型 成員變量名 [=默認值]
~~~
* 修飾符:可以省略,也可以是public /protected / private / static / final ,其中public protected private 只允許出現其中的一個。
* 數據類型:可以是任意的數據類型。(包含基本數據類型,類類型,數組類型)
* 默認值:如果是類類型的,沒有定義默認值,那么成員變量的值為null,如果是基本數據類型,沒有定義默認值,那么成員變量的值是有意義的,比如說int類型的值就是0,boolean類型的值就是false。
## 方法
語法:
~~~
[修飾符] 方法的返回值的數據類型 方法名([形參列表]) {
方法體語句;
}
~~~
* 修飾符:可以省略,也可以是public /protected / private / static / final ,其中public protected private 只允許出現其中的一個。
* 返回值: 可以是數據類型(不要忘了自定義個數據類型),也可以是void,如果我們定義了返回值,那么久必須在**return后面跟隨該類型的值或對象**
* 方法名: 一般是首字母小寫,也適用駝峰原則,一般是動詞在前,名詞在后,不易過長。
* 形參列表: 定義方法可以接受的參數,由0個-n個\[數據類型 參數名\] 通過\*\*,\*\*進行組合,一旦這個方法指定了形參,那么在調用的時候就必須一一對應的傳入參數(實際參數)
關于參數的補充說明:
1. 實參:是確定數字,文字,數組等實際內容,所以稱之為實際參數。多用于在調用這個方法的時候傳入實際參數。
2. 形參:形參是形式參數的簡稱。它只是一種形式,不是具體的值。相當于數學中的代數,代表著一個數而已。
2.1 形參的作用:
* 定義了一個局部的變量,在方法的內部可以調用
* 外部調用這個方法的時候,告訴調用者這個方法需要什么樣的參數。
## static 關鍵字
用于修飾成員變量和方法。用static修飾的成員變量和方法,是屬于**類**的,而不是屬于該**類的實例(對象)**。
通常我們把static修飾的成員變量稱之為【類變量,靜態變量】,方法稱之為【類方法,靜態方法】
>[danger] 靜態的成員是不能訪問非靜態成員的
> 靜態成員之間是可以相互訪問的
~~~
public static int age=18;
static String fun() {
System.out.println(age);
return "";
}
String fun2() {
System.out.println(this.age);
return "";
}
~~~
## 使用一個對象的過程
* 定義類
* 構建和使用對象
語法:
~~~
類類型 對象名 = new 構造器方法();
~~~
實例:
~~~
Person dongdong = new Person();
~~~
**在內存中的執行過程**
1. 在棧內存中,會存儲對象名, 在沒有執行構造器創建對象并賦值是,此時對象名對應的值應為null
2. 通過new關鍵字調用類的構造器在堆內存中分配了一塊對象區域;
3. 通過賦值運算符= ,將堆內存中的對象地址賦給棧內存中的變量名;
4. 例如再次給對象的屬性賦值: 通過棧內存中的地址定位到對象在堆內存中的地址,找到相應的成員變量,進行一個賦值操作
>[info] 引用: 引用還可以稱之為【地址】,【指針】 。特指的示類類型。因為只用類類型才會在堆內存中分配對象空間,并將地址(指針)在棧內存中用于對象變量名的引用。
## this關鍵字
Java中使用this關鍵字,指向調用該方法的對象。根據this所在的位置,大致分為兩種情況
* 出現在構造器中:引用該構造器正在初始化的對象
* 出現在普通方法中: 正在調用該方法的對象
this用在類定義中,獲取當前對象的屬性,或者調用當前對象的方法
>[warning]在類定義中,可以省略this關鍵字去調用屬性或者方法,但是在類被編譯的時候,編譯器還是會加上this關鍵字。所以我們強烈建議在類定義的時候如果要調用該類中的普通成員變量或者方法,還是要把this給加上去
> 用static修飾的方法是不能使用this關鍵字的
~~~
public class Students {
public static void main(String[] args) {
Students ding = new Students("丁潤萌","001",18);
ding.listen();
System.out.println(ding.fun1());
}
String name;
String code;
int age;
public Students(String name, String code, int age) {
super();
this.name = name;
this.code = code;
this.age = age;
}
public Students() {
super();
}
/**
* 自我介紹
* @return
*/
String intro() {
return "我叫" + this.name + ", 我的學號是" + this.code + ", 我今年" + this.age + "歲了";
}
void listen() {
System.out.println("自我介紹" + this.intro() + " " + this.name + "正在上課");
}
//錯誤實例
/*static String fun2() {
return this.intro();
}*/
static String fun() {
return "Hello,world";
}
//錯誤實例
String fun1() {
this.fun();
return "Hello";
}
}
~~~