【Java 從入坑到放棄】No 7. 何為面向對象(上)
前言
前面已經(jīng)講了 Java 的一些環(huán)境搭建、IDE 使用、變量及數(shù)據(jù)類型、操作符、控制流程以及數(shù)組操作,今天就來看看 Java 里邊的一個核心思想 - 面向對象編程。內(nèi)容預告如下:
面向對象簡介 面向對象實例
面向對象
什么是面向對象?
所謂面向對象,是一種通過對象的方式,將現(xiàn)實中的事物映射到計算機模型的一種編程方法;
對象的含義指的是具體的某一個事物,即我們在現(xiàn)實生活中能夠看得見摸得著的。在面向對象程序設計中,對象指的是計算機系統(tǒng)中的某一個成分,主要有兩層含義。一個是指 數(shù)據(jù),另一個則是 動作。即對象是兩者的結合體,通過對象不僅能夠進行操作,還能對操作的結果進行記錄。
在這之前,另一種編程方式是 面向過程,用一個具體的例子來講,可以描述成下面這樣:
假如有一天你很想吃酸菜魚,那么你該怎么辦呢?下面就以面向對象和面向過程給你兩個選擇,讓你決定來選哪一個!
面向對象:打開手機,打開外賣軟件,搜索酸菜魚,然后下單,等著外賣送到家就行! 面向過程:先去買菜,魚、酸菜、調料……,然后回家殺魚、切酸菜、切調料……,再接著開始炒,最后做好盛到盤子里!
對比可以發(fā)現(xiàn)兩者的優(yōu)缺點:
面向過程 優(yōu)點:性能好;以例子來說自己做比起點外賣,經(jīng)濟又實惠,還吃得放心; 缺點:不易維護、不易復用、不易擴展;以例子來講,要是我們自己做,臨時又想吃其他的菜,又得跑去買材料啥的,麻煩!但外賣就不一樣了,直接打開手機再點就是! 面向對象 優(yōu)點:易維護、易復用、易擴展,也就是面向過程的缺點; 缺點:性能較差;比起自己做,點外賣成本啥的可能就比較高了;
面向對象的 3 大特性
封裝
隱藏對象的屬性和實現(xiàn)細節(jié),對外只提供訪問的接口,提高復用性和安全性;
繼承
定義父類之后,子類可以從基礎類進行繼承,提高了代碼的復用率,重要的一點:類只能單繼承;
多態(tài)
父類或者接口定義的引用變量可以指向子類或具體實現(xiàn)類的實例對象,提高了程序的擴展性;
面向對象的 5 大原則
單一職責原則 SRP
類的功能要單一,不能太復雜;
開放封閉原則 OCP
一個模塊對于擴展是開放的,對于修改則是封閉的,可以增加功能,但是修改功能卻不行;
里氏替換原則 LSP
子類能夠替換父類出現(xiàn)在父類能夠出現(xiàn)的任何地方;
依賴倒置原則 DIP
高層次的模塊不應該依賴于低層次的模塊,而應該都依賴于抽象。抽象不應該依賴于具體實現(xiàn),但具體實現(xiàn)應該依賴于抽象;
接口分離原則 ISP
設計時采用多個與特定客戶類相關的接口比采用一個通用接口要好;
面向對象的具體實例
類與對象
以我們?nèi)粘I顬槔覀儸F(xiàn)在很多人都養(yǎng)寵物,而寵物 都有一些共同狀態(tài),比如名字、毛色、年齡…… 這樣一來我們就可以設計一個叫做 類 的東西,用來 代表寵物 這一類事物;
public class Pet{
// 名字
public String name;
// 毛色
public String furColor;
// 年齡
public int age;
}
有了這個類之后,它就相當于我們的一個模板,根據(jù)這個模板我們就能夠創(chuàng)建一個個具體的寵物,而這些寵物,就叫做 對象;
public class Pet{
// 名字
public String name;
// 毛色
public String furColor;
// 年齡
public int age;
public static void main(String[] args){
// 創(chuàng)建一個對象
Pet dog = new Pet();
dog.name = "博美";
dog.furColor = "white";
dog.age = 1;
Pet cat = new Pet();
cat.name = "英短";
cat.furColor = "orange";
cat.age = 2;
}
}
屬性
每個寵物都有自己的名字、毛色和年齡等一系列狀態(tài),而這些狀態(tài)就叫做一個類的 屬性。而屬性的類型既可以是基本類型(比如上述例子中的 int),也可以是引用類型(上述例子中的 String)。而在 Java 語言中,屬性的命名雖然沒有強制規(guī)定,但是一般都是有一套大家通用的命名方法,即:
若屬性是一個單詞組成,那么一般都是小寫;
若屬性是多個單詞組成,那么則采用駝峰法;
關于更多的命名規(guī)定,推薦參考阿里巴巴出品的 《Java 開發(fā)手冊》,下載地址:https://github.com/cunyu1943/amazing-books
方法
而除開屬性之后,每個對象還能夠有許多其他的功能,就像寵物都能吃東西、會叫……,那么這些他們能夠做的事情,在類里邊就可以用 方法 來進行表示;
public class Pet{
// 名字
public String name;
// 毛色
public String furColor;
// 年齡
public int age;
// 吃東西對應的方法
public void eat(){
System.out.println("吃東西!");
}
// 叫喚對應的方法
public void bark(){
System.out.println("叫喚!");
}
}
而對于方法,也有需要注意的幾點:
方法是可以有返回值的,如果要返回對應值,則其返回值的類型要與返回值相對于,對于不需要返回值的方法,則將其返回類型設置為 void;方法是可以有參數(shù)的,我們上述例子的方法中都是不帶參數(shù)的,但如果我們有需要,就可以加上自己需要的參數(shù),但此時注意要帶上參數(shù)的類型;
總結起來,可以分為如下四種方法:
無參無返回值
public void methodName(){
……
}
無參有返回值
public boolean methodName(){
……
return false;
}
有參無返回值
public void methodName(String name){
……
}
有參有返回值
public boolean methodName(String name){
……
return false;
}
public class Pet{
// 名字
public String name;
// 毛色
public String furColor;
// 年齡
public int age;
// 具有返回值的方法
int getAge(){
return age;
}
// 帶有參數(shù)的方法
void setAge(int age){
this.age = age;
}
// 吃東西對應的方法
void eat(){
System.out.println("吃東西!");
}
// 叫喚對應的方法
void bark(){
System.out.println("叫喚!");
}
}
而對于方法命名的方式,也是有一定講究的。因為一般而言方法都是一個類的動作行為,所以 一般都是以動詞開頭,而如果有多個單詞組合,則除開第一個單詞全部小寫之外,后面每個單詞的第一個字母都要使用大寫。
構造方法
上面我們說了實例(也就是對象)和屬性,那么當我們創(chuàng)建一個實例的時候,通常我們想要把它的屬性也給它設置好。為了實現(xiàn)這一功能,這時候我們可以添加方法,從而達到這一目的,以上述設置寵物的年齡為例。
// 首先創(chuàng)建一個實例
Pet pet = new Pet();
// 接著調用方法設置年齡
pet.setAge(3);
// 查看設置年齡是否成功
System.out.println(pet.getAge());
可以發(fā)現(xiàn)通過上述調用方法的方式是可以完成這一目的的,但假設我們需要設置的屬性很多,此時要全部設置屬性值時就需要調用許多次 setter 方法,一旦遺漏一個,則實例內(nèi)部狀態(tài)就紊亂了。那我們就想了,有沒有一種簡單點的方法,能夠讓我們在創(chuàng)建實例對象的同時就把內(nèi)部屬性初始化了呢?
答案是:Yes!??????
這時候我們就可以用到一類特殊的方法 - 構造方法,以下就來看看這個構造方法的特殊之處。
其實在上面我們創(chuàng)建實例的時候就已經(jīng)調用了構造方法了,只不過它是沒有帶任何參數(shù)的構造方法。以上述動物類 Pet 為實例,我們來看看如何編寫它的構造方法。
public class Pet{
// 名字
public String name;
// 毛色
public String furColor;
// 年齡
public int age;
// 無參構造方法
public Pet(){}
// 帶參構造方法
public Pet(String name, String furColor, int age){
this.name = name;
this.furColor = furColor;
this.age = age;
}
}
以上我們只是給出了無參的構造方法和帶了所有屬性的構造方法,除了上面的兩個構造方法之外,我們還可以根據(jù)需要創(chuàng)建帶有部分屬性的構造方法。可以看到,相比于普通的方法,構造方法有著明顯的特點:
沒有返回值:是的,無論是帶參還是不帶參的構造函數(shù),它們都是沒有返回值的,而它也是 每個類默認的構造方法; 方法名同類名一樣:必須確保構造方法的名字和類名一致,否則它就不是構造方法了;
有了構造方法之后,我們創(chuàng)建實例時就可以直接給它初始化了,而不用再去麻煩地調用各個 setter 方法來初始化實例。
// 調用無參構造方法
Pet pet1 = new Pet();
// 調用有參構造方法
Pet pet2 = new Pet("柯基", "黃色", 1);
?? Tips:對于實例的屬性值,在未經(jīng)構造方法初始化時,各數(shù)據(jù)類型都有默認值,整型默認值為 0,浮點型默認值為 0.0,布爾類型默認值為 false,引用類型默認值為 null。
引用
既然知道了什么是面向對象以及面向對象中的一些關鍵知識點如對象、屬性、方法的概念,那我們就趁熱來看看啥是引用。
所謂引用,其實在之前學習的時候就已經(jīng)涉及到了。你是否還記得 String 這個特殊的數(shù)據(jù)類型,其實在我們創(chuàng)建一個 String 對象時,也就創(chuàng)建了一個引用。
String str = new String("村雨遙");
其中 str 既是一個變量,也是一個引用,指向一個值為 "村雨遙" 的 String 對象,后續(xù)如果我們要訪問這個 String 對象,就需要使用 str 這個引用來代表它。

以上我們說的是一個引用指向一個對象,但是我們也可以用多個引用指向同一個對象。就好比你家買了一倆車,不僅你可以開,你老婆也可以開,你爸媽也可以開。而這時候的車就好比一個“對象”,而使用它的人就是多個“引用”。
// 對象 1
String str1 = new String("村雨遙");
// 對象 2
String str2 = str1;
// 對象 3
String str3 = str1;

總結
XDM,今天的內(nèi)容就到此結束了。主要講了面向對象的相關概念以及特性,并對面向對象中的類、對象、屬性、方法、構造方法以及引用做了介紹,關于更多面向對象的知識,我們下一篇文章中再見!



