掌握J(rèn)ava面向?qū)ο驩OP篇(一)
掌握面向?qū)ο驩OP篇(一)
邊學(xué)邊記 -- OOP(Object Orientated Programing)
1.1 非面向?qū)ο?/h3>
不使用面向?qū)ο螅?/p>
package study;
import java.util.Scanner;
public class oobject1 {
public static void main(String[] agrs){
// 小白狗
String dogName = "小白";
int dogAge = 2;
String dogColor = "白色";
// 小紅狗
String dogName1 = "小紅";
int dogAge1 = 2;
String dogColor1 = "白色";
Scanner scanner = new Scanner(System.in);
System.out.println("請輸入狗的名字:");
String queryDogName = scanner.nextLine();
if(queryDogName.equals("小紅")){
System.out.println("狗名: " + dogName1 + "\n" + "狗齡: " + dogAge1 + "\n" + "顏色: " + dogColor1);
}else if (queryDogName.equals("小白")){
System.out.println("狗名: " + dogName + "\n" + "狗齡: " + dogAge + "\n" + "顏色: " + dogColor);
}else {
System.out.println("該寵物點沒有這條狗");
}
}
}
class oobject2{
public static void main(String[] args){
String[] dogName = {"小白","小紅"};
int[] dogAge = {2,3};
String[] dogColor = {"白色","紅色"};
System.out.println("請輸入狗名:");
Scanner s = new Scanner(System.in);
String queryDogName = s.nextLine();
boolean flag = false;
for(int i=0;i<dogName.length;i++){
if(queryDogName.equals(dogName[i])){
System.out.println("狗名: " + dogName[i] + "\n" + "狗齡: " + dogAge[i] + "\n" + "顏色: " + dogColor[i]);
flag = true;
}
}
if(!flag){
System.out.println("該寵物點沒有這條狗");
}
}
}
輸出結(jié)果:

class oobject3{ private String dogName; private int dogAge; private String dogColor; public oobject3(String dogName,int dogAge,String dogColor){ this.dogName = dogName; this.dogAge = dogAge; this.dogColor = dogColor; } public void getInfo(){ System.out.println("狗名: " + dogName + "\n" + "狗齡: " + dogAge + "\n" + "顏色: " + dogColor); } public String getDogName(){ return dogName; } public static void main(String[] args){ // 創(chuàng)建兩只狗,也就是兩只對象 oobject3 whiteDog = new oobject3("小白",2,"白色"); oobject3 reDog= new oobject3("小紅",3,"紅色"); // 用戶輸入狗的名字 Scanner scanner = new Scanner(System.in); System.out.print("請輸入狗的名字:"); String queryDogName = scanner.nextLine(); if(queryDogName.equals(whiteDog.dogName)){ whiteDog.getInfo(); }else if (queryDogName.equals(reDog.dogName)){ reDog.getInfo(); }else { System.out.println("該寵物點沒有這條狗"); } } }

由上面兩個例子,我們從代碼的角度去看,為什么引入面向?qū)ο髸奖恪?/p>
當(dāng)不使用面向?qū)ο蟮姆绞剑捎脭?shù)組或獨立變量的方式進(jìn)行編程時,每個“對象”(這里是指表示狗的信息)都需要通過獨立的變量或數(shù)組元素進(jìn)行定義。這意味著對于每一只狗,都需要單獨聲明和初始化相關(guān)的變量。當(dāng)我們有成千上萬個這種“對象”時,就需要重復(fù)定義更多的代碼,這就會導(dǎo)致:
1.冗余和代碼膨脹:隨著狗的數(shù)量的增加 ,代碼中的相似的定義和初始化操作變得冗余。這導(dǎo)致了代碼的膨脹,使得程序變得龐大且難以維護(hù)。
//比如:我們需要反復(fù)的使用String dogName = "example";等等去定義屬性。
2.可讀性很差: 大量的重復(fù)代碼使得程序的可讀性變差。維護(hù)人員很難在代碼中找到并理解與每只狗相關(guān)的所有信息。
//因為代碼中有大量的對屬性的定義,所以很難對應(yīng)找到
3.難以修改:如果我們要對狗的屬性進(jìn)行修改、或者添加新的屬性,那么整個代碼的維護(hù)更新就會非常難以進(jìn)行,并且容易出錯。
//當(dāng)代碼量上來的時候,我們?nèi)绻o狗添加一個毛的長短的屬性,那么我們就要添加幾萬行代碼,很不合理。
4.缺乏結(jié)構(gòu)性:獨立變量或數(shù)組元素的方式缺乏結(jié)構(gòu),不易于組織和管理相關(guān)的信息。隨著信息的增加,代碼可能變得混亂且難以理解。
//代碼看起來沒有章法,不知道從哪里入手
使用面向?qū)ο蟮暮锰幹饕w現(xiàn)在以下幾個方面:
1.封裝和抽象: 面向?qū)ο缶幊虖娬{(diào)封裝,將對象的屬性和行為封裝在一起,提供了更高層次的抽象。這使得程序員可以專注于對象的接口,而不必關(guān)心內(nèi)部的實現(xiàn)細(xì)節(jié)。這樣的封裝和抽象提高了代碼的模塊化和可維護(hù)性。
//比如我們的oobject3中的非主類部分,就是把屬性和方法放在了(封裝)類oobject3中,那么這個時候我們的主類去 new 出一個對象時,就可以直接使用這些屬性和方法。因為這個方法和屬性被封裝成為了一個模板。我們通過這個模板new的狗子的這些屬性和方法的使用都一樣。那么這個模板就實現(xiàn)了很好的統(tǒng)一也降低了代碼的重復(fù)量。這就是封裝的好處。
2.可維護(hù)性和可擴展性: 面向?qū)ο蟮木幊棠P褪沟么a更易于維護(hù)和擴展。通過創(chuàng)建類和對象,可以輕松地添加新的功能或修改現(xiàn)有功能,而不必改變整個程序的結(jié)構(gòu)。這種靈活性使得程序更具可維護(hù)性和可擴展性。
//當(dāng)我們要添加屬性時,我們只需要在oobject3中加一行代碼,private String type; 那么所有的狗就可以用這個屬性,不用去大量的改動代碼。
3.代碼重用: 面向?qū)ο蟮脑O(shè)計強調(diào)重用性。通過創(chuàng)建類和繼承,可以在不同的地方重復(fù)使用相同的代碼。這降低了重復(fù)編碼的需求,提高了開發(fā)效率。
4.繼承和多態(tài): 繼承和多態(tài)是面向?qū)ο缶幊痰膬蓚€核心概念。繼承允許創(chuàng)建一個類,繼承另一個類的屬性和方法,從而實現(xiàn)代碼的重用。多態(tài)性允許同一個方法在不同的對象上表現(xiàn)出不同的行為,提高了代碼的靈活性和可擴展性。
//在上面的例子中沒有涵蓋對繼承和多態(tài)的理解,在下面會有
更好的組織結(jié)構(gòu): 面向?qū)ο蟮脑O(shè)計強調(diào)將現(xiàn)實世界的問題映射到代碼結(jié)構(gòu)中。通過創(chuàng)建類和對象,能夠更自然地模擬問題領(lǐng)域中的實體和關(guān)系,使得代碼更易于理解和維護(hù)。
團隊協(xié)作: 面向?qū)ο蟮脑O(shè)計使得多人協(xié)作更為容易。每個類可以被視為一個獨立的模塊,不同的團隊成員可以獨立地開發(fā)和測試各自負(fù)責(zé)的類。這有助于提高團隊的生產(chǎn)力和協(xié)作效率。
所以在Java中引入面向?qū)ο螅约笆褂妹嫦驅(qū)ο蠖际潜匾摹?/p>
2. 面向?qū)ο?VS 面向過程
這里假設(shè)面試官問你面向?qū)ο蠛兔嫦蜻^程的區(qū)別,我們怎么回答?(已經(jīng)汗流浹背了 ~ )
2.1 語言
面向?qū)ο笳Z言:
- Java :毋庸置疑,Java一切皆對象,肯定是面向?qū)ο缶幊?/li>
- C++ :一種支持 面向?qū)ο蠛兔嫦蜻^程編程的語言
- C#(C Sharp): 由Microsoft開發(fā),用于.NET平臺,支持面向?qū)ο缶幊毯推渌F(xiàn)代編程概念。
- Python : Python是一種多范式的編程語言,支持面向?qū)ο缶幊獭⒚嫦蜻^程編程以及函數(shù)式編程。
- Ruby: 一種動態(tài)腳本語言,以其簡潔而強大的面向?qū)ο筇匦远軞g迎。
- Swift: 由Apple開發(fā),專為iOS和macOS設(shè)計,具有現(xiàn)代化的面向?qū)ο筇匦浴?/li>
- Objective-C: 用于iOS和macOS的編程語言,支持面向?qū)ο缶幊獭?/li>
面向過程語言:
- C: 一種廣泛使用的面向過程編程語言,以其效率和直接的硬件訪問而受歡迎。
- C++ :C++是一種多范式的編程語言,它既支持面向?qū)ο缶幊蹋ň哂蓄悺⒗^承等特性),也支持面向過程編程。在C++中,你可以采用純粹的面向過程的編碼風(fēng)格,就像在C語言中一樣。
- Python : Python也是一種多范式的編程語言,支持面向?qū)ο缶幊獭⒚嫦蜻^程編程以及函數(shù)式編程。盡管Python提供了豐富的面向?qū)ο筇匦裕苍试S開發(fā)者采用面向過程的編程風(fēng)格。
- Fortran: Fortran是一種主要用于科學(xué)和工程計算的編程語言,以其數(shù)值計算和面向過程的特性而著稱。
2.2 OOP vs OPP
" 這個引用來自狂神Java "
語言的進(jìn)化發(fā)展跟生物的進(jìn)化發(fā)展其實是一回事,都是”物以類聚”。
相近的感光細(xì)胞聚到一起變成了我 們的眼睛,相近的嗅覺細(xì)胞聚到一起變成了我們的鼻子。 語句多了,我們將完成同樣功能的相近的語句,聚到了一塊兒,便于我們使用。于是,方法出現(xiàn)了! 變量多了,我們將功能相近的變量組在一起,聚到一起歸類,便于我們調(diào)用。于是,結(jié)構(gòu)體出現(xiàn)了! 再后來,方法多了,變量多了!結(jié)構(gòu)體不夠用了!我們就將功能相近的變量和方法聚到了一起,于是類 和對象出現(xiàn)了! 寥寥數(shù)語,就深刻的展示了語言的進(jìn)化歷史!其實,都非常自然,”物以類聚”。希望大家能記住這句 話。 企業(yè)的發(fā)展也是”物以類聚”的過程,完成市場推廣的人員聚到一起形成了市場部。完成技術(shù)開發(fā)的人員 聚到一起形成了開發(fā)部!
面向?qū)ο蠛兔嫦蜻^程的本質(zhì)區(qū)別就是處理邏輯(思維模式)的不同。
1.面向過程的思維模式就是簡單的線性思維,解決問題首先陷入第一步干什么、第二部干什么的細(xì)節(jié)中。這種思維模式適合處理一些簡單的事務(wù),別入從A走到B,把垃圾倒入垃圾桶等等。如果面對復(fù)雜的問題,那么解決就會很麻煩。
2.相反,面向?qū)ο蟾⒅氐氖菍栴}的整體抽象和建模。它將問題中的實體抽象為一個個的對象,關(guān)注對象之間的交互。讓對象去解決問題,這樣的思維模式更加自然,更加貼近生活。
考慮一個復(fù)雜任務(wù),比如設(shè)計并制造一艘航天飛船,面向過程的思維模式可能會讓人感到困擾,因為這需要考慮眾多細(xì)節(jié)和步驟。然而,通過面向?qū)ο蟮乃季S模式,我們可以將這個龐大的任務(wù)分解成對象,例如“引擎”、“控制系統(tǒng)”、“艙體”等,每個對象都有特定的屬性和行為。這種抽象和分解使得我們能夠更清晰地理解并解決問題,而不會被淹沒在無盡的步驟中。
package study; abstract class shape { private String color; //構(gòu)造方法 public shape(String color){ this.color = color; } public String getColor(){ return color; } //多態(tài)的體現(xiàn)之處 public abstract double getArea(); } class Circle extends shape{ private double radius; public Circle(String color ,double radius) { super(color); this.radius = radius; } @Override public double getArea() { return Math.PI * Math.pow(radius,2); } } class Rectangle extends shape{ private double len; private double width; public Rectangle(String color,double len , double width) { super(color); this.len = len; this.width = width; } @Override public double getArea() { return len * width; } } public class oobject2 { public static void main(String[] args) { // 創(chuàng)建 Circle 對象 Circle circle = new Circle("Red", 5.0); System.out.println("Circle Area: " + circle.getArea()); System.out.println("Circle Color: " + circle.getColor()); // 創(chuàng)建 Rectangle 對象 Rectangle rectangle = new Rectangle("Blue", 4.0, 6.0); System.out.println("Rectangle Area: " + rectangle.getArea()); System.out.println("Rectangle Color: " + rectangle.getColor()); } }
上面的例子中,我們很清楚的可以看到Java中封裝、繼承、多態(tài)的好處。下面我在贅述一遍 ┭┮﹏┭┮
我們在抽象類 shape中將color屬性被聲明為私有(private),外部類無法直接訪問。顏色的訪問和設(shè)置通過公共方法getColor進(jìn)行,這體現(xiàn)了封裝的概念、隱藏類內(nèi)部實現(xiàn)細(xì)節(jié)。
Circle 和 Rectangle 子類繼承了 Shape 類,并通過調(diào)用 super(color) 訪問了父類的構(gòu)造方法,這也是一種封裝的體現(xiàn),子類不需要直接訪問父類的私有屬性。
封裝的好處:
封裝提高了代碼的安全性:將屬性聲明為私有,通過公有方法進(jìn)行訪問,防止外部直接修改對象的內(nèi)部狀態(tài)值,從而提高數(shù)據(jù)的安全性。
封裝隱藏細(xì)節(jié):封裝允許隱藏內(nèi)部實現(xiàn)細(xì)節(jié),使得使用者只需要關(guān)注對象的公有接口。這樣的設(shè)計可以降低了系統(tǒng)的復(fù)雜性,是代碼更容易理解和維護(hù)。
封裝提高靈活性:如果內(nèi)部實現(xiàn)需要更改,只需保持公有接口不變,使用者不受影響。這種靈活性使得系統(tǒng)更容易適應(yīng)變化。
在 Circle 和 Rectangel 類都是通過關(guān)鍵字extends繼承自shape 抽象類。這使得子類獲得了父類的屬性和方法,實現(xiàn)了代碼的重用。例如:兩個類都繼承父類的color屬性和getColor方法。
繼承的好處:
代碼重用: 繼承允許子類重用父類的代碼,避免了重復(fù)編寫相似的代碼,降低了代碼的重復(fù)率。
可維護(hù)性: 當(dāng)需要修改或擴展功能時,只需在父類中進(jìn)行修改,子類將自動繼承這些變化。這降低了修改代碼的風(fēng)險,提高了可維護(hù)性。
多態(tài)支持: 繼承是實現(xiàn)多態(tài)的基礎(chǔ)。通過繼承,不同的子類可以被視為同一類型的對象,提供了更靈活的代碼結(jié)構(gòu)。
在 shape抽象類的抽象方法getArea中體現(xiàn)了多態(tài)。不同的子類分別重寫了這個方法,根據(jù)自己的需求提供了具體的實現(xiàn)。在測試類中,通過統(tǒng)一的接口 getArea 調(diào)用,實際上調(diào)用了各個子類的實現(xiàn),展現(xiàn)了多態(tài)性。
多態(tài)的好處:
靈活性和擴展性: 多態(tài)允許同一類型的對象以不同的方式響應(yīng)相同的方法調(diào)用。這提高了代碼的靈活性和可擴展性,使得系統(tǒng)更容易適應(yīng)變化。
簡化代碼: 多態(tài)性允許使用者通過一個統(tǒng)一的接口調(diào)用不同類型的對象,簡化了代碼,提高了可讀性。
實現(xiàn)抽象概念: 多態(tài)性使得我們能夠以更抽象的方式思考和設(shè)計問題,將實際對象視為抽象概念的實例,有助于更清晰地理解和解決問題。
本文來自博客園,作者:Liberty碼農(nóng)志,轉(zhuǎn)載請注明原文鏈接:http://www.rzrgm.cn/zhiliu/p/17843787.html

浙公網(wǎng)安備 33010602011771號