Java 设计模式 Day3 之面向抽象原则:什么是面向抽象编程?面向抽象编程如何应用?
文章目錄
- 前言
- 一、什么是面向抽象編程?
- 二、傳統(tǒng)場景的類設(shè)計
- 2.1、項目場景設(shè)計
- 2.2、傳統(tǒng)類設(shè)計存在的問題
- 三、采用面向抽象編程的類設(shè)計
- 3.1、設(shè)計一個抽象類/接口
- 3.2、采用上轉(zhuǎn)型對象/接口回調(diào)調(diào)用子類方法
- 3.3、重新設(shè)計子類/被實現(xiàn)類
- 3.4、面向抽象編程的具體實現(xiàn)
- 四、面向抽象編程的優(yōu)勢
- 總結(jié)
前言
面向抽象原則是面向?qū)ο笏拇蠡驹瓌t的第一條,其重要性不言而喻,面向抽象原則分為抽象類、接口以及面向抽象編程,在之前的內(nèi)容中我們詳細(xì)介紹了抽象類與接口,并對二者進(jìn)行了對比,在本文中我們將詳細(xì)介紹什么是面向抽象編程,它與傳統(tǒng)編程相比有什么優(yōu)勢?在開發(fā)中又該如何切實應(yīng)用。一、什么是面向抽象編程?
面向抽象編程就是在設(shè)計一個類時,不讓該類面向具體的類,而是面向抽象類或接口,即所設(shè)計的類中的重要數(shù)據(jù)是抽象類或接口聲明的變量,而不是具體類聲明的變量。
下面我們將在具體的案例中進(jìn)一步分析傳統(tǒng)類設(shè)計與面向抽象編程的類設(shè)計的區(qū)別。
二、傳統(tǒng)場景的類設(shè)計
在探討面向抽象編程之前,先看一下我們常規(guī)對于一個類的設(shè)計是什么樣的。
2.1、項目場景設(shè)計
項目場景:現(xiàn)在我們需要求一個圓柱體的體積,需要創(chuàng)建兩個類,圓類 Circle 和圓柱體類 Pillar。
首先我們創(chuàng)建一個 Circle 類,該類創(chuàng)建的對象 circle 調(diào)用 getArea() 方法可以計算出圓的面積,Circle 類的代碼如下:
package com.bailu.principle;public class Circle {final double PI = 3.14159;// 定義一個常量double r;/** 定義一個無參構(gòu)造*/Circle() {}Circle(double r) {this.r = r;}public double getArea() {return (PI * r * r);} }接著我們再設(shè)計一個圓柱類 Pillar,該類創(chuàng)建的對象 pillar 調(diào)用 getVolume() 方法可以計算圓柱體的體積,Pillar 類的代碼如下:
package com.bailu.principle;public class Pillar {Circle bottom;// 將Circle類聲明的對象作為成員,圓柱體的底double height;/** 定義一個無參構(gòu)造*/Pillar() {}Pillar(Circle bottom, double height) {this.bottom = bottom;this.height = height;}public double getVolume() {return bottom.getArea() * height;} }2.2、傳統(tǒng)類設(shè)計存在的問題
在上面的圓柱體類 Pillar 中,bottom 是用具體類 Circle 聲明的變量,如果在實際開發(fā)中不涉及用戶需要的變化,這樣設(shè)計并沒有什么不妥,但是某些時候,如果用戶希望將圓柱體改為三菱柱。顯然 Pillar 類是無法滿足的,并不能滿足用戶的需求。
那我們就需要對 Pillar 類進(jìn)行修改。對于需要我們需要明確,柱體計算體積關(guān)鍵點在于計算底面積。我們不應(yīng)該關(guān)心它的底具體是什么樣的形狀,而應(yīng)該關(guān)心是否有計算面積的方法。
即我們在設(shè)計類的時候不應(yīng)該將柱體的底看做某個具體類聲明的變量,我們上面這樣做,Pillar 類太過于依賴具體類,缺乏彈性,難以應(yīng)對需求的變化。
三、采用面向抽象編程的類設(shè)計
3.1、設(shè)計一個抽象類/接口
如果我們采用面向抽象編程重新進(jìn)行設(shè)計,首先需要設(shè)計一個抽象類用來獲取柱體底面積,該抽象類(或接口)我們定義為 Geometry(),我們在其中定義一個 getArea() 的抽象方法,具體代碼如下:
package com.bailu.principle;public abstract class Geometry {// 如果使用的是接口,用interface定義即可public abstract double getArea(); }現(xiàn)在我們就可以面向 Geometry 類進(jìn)行編碼,即通過上轉(zhuǎn)型對象/接口回調(diào)的方式,調(diào)用 Geometry 子類重寫的 getArea() 方法,這樣 Pillar 類就可以將計算柱體底面積的任務(wù)指派給 Geometry 子類的實例。
3.2、采用上轉(zhuǎn)型對象/接口回調(diào)調(diào)用子類方法
現(xiàn)在我們重新設(shè)計 Pillar 類不再依賴具體類,而是面向我們創(chuàng)建的抽象類/接口 Geometry,即 bottom 不再是具體類 Circle 聲明的變量,重新設(shè)計后 Pillar 類代碼如下:
package com.bailu.principle;public class Pillar {Geometry bottom;// bottom是抽象類Geometry聲明的變量double height;/** 定義一個無參構(gòu)造*/Pillar() {}Pillar(Geometry bottom, double height) {this.bottom = bottom;this.height = height;}public double getVolume() {return bottom.getArea() * height;// bottom可以調(diào)用子類重寫的getArea()方法} }3.3、重新設(shè)計子類/被實現(xiàn)類
在采用面向抽象編程之后,我們就可以根據(jù)客戶需求對柱體要求的不同底進(jìn)行設(shè)計。如圓形底和矩形底,我們創(chuàng)建抽象類 Geometry 的子類 Circle 和 Rectangle,重寫 Geometry 類的抽象方法 getArea()計算各自面積。
Circle 類對應(yīng)代碼如下:
package com.bailu.principle;/** 當(dāng)柱體的底為圓時*/ public class Circle extends Geometry {final double PI = 3.14159;// 定義一個常量double r;/** 定義一個無參構(gòu)造*/Circle() {}Circle(double r) {this.r = r;}@Overridepublic double getArea() {return (PI * r * r);} }Rectangle 類對應(yīng)代碼如下:
package com.bailu.principle;/** 當(dāng)柱體的底為矩形時*/ public class Rectangle extends Geometry {double a, b;// 定義矩形的長寬/** 創(chuàng)建一個無參構(gòu)造*/Rectangle() {}Rectangle(double a, double b) {this.a = a;this.b = b;}@Overridepublic double getArea() {return a * b;} }3.4、面向抽象編程的具體實現(xiàn)
現(xiàn)在我們就可以使用 Pillar 類創(chuàng)建出不同形狀底的柱體了,實現(xiàn)代碼如下:
package com.bailu.principle;public class ApplicationPillar {public static void main(String[] args) {Pillar pillar;Geometry bottom;bottom = new Rectangle(2, 3);// 抽象類的實例作為Rectangle類的上轉(zhuǎn)型對象pillar = new Pillar(bottom, 3);System.out.println("矩形底柱體體積為: " + pillar.getVolume());bottom = new Circle(2);// 抽象類的實例作為Circle類的上轉(zhuǎn)型對象pillar = new Pillar(bottom,2);System.out.println("圓底柱體體積為: " + pillar.getVolume());} }運行結(jié)果具體如下圖所示:
四、面向抽象編程的優(yōu)勢
通過上面的案例我們可以發(fā)現(xiàn),采用面向編程來設(shè)計 Pillar 類,使得 Pillar 類不再依賴于具體的某個類(Circle 類、Rectangle 類),當(dāng)我們有新的需求增加時,我們只需要增加 Geometry 的子類即可,如增加一個三角形底的子類 Triangle,并不需要修改 Pillar 類的任何代碼就可以創(chuàng)建出三角形底的柱體。
總結(jié)
在本文給大家介紹了什么是面向抽象編程,并通過與傳統(tǒng)類設(shè)計的對比使大家明確面向抽象編程的優(yōu)勢,設(shè)計一個類時,不讓該類面向具體的類,而是面向抽象類或接口,即所設(shè)計的類中的重要數(shù)據(jù)是抽象類或接口聲明的變量,而不是具體類聲明的變量,這樣就算需求發(fā)生變化,我們只需要增加或修改抽象類子類內(nèi)容即可,而無需修改其他代碼。我是白鹿,一個不懈奮斗的程序猿。望本文能對你有所裨益,歡迎大家的一鍵三連!若有其他問題、建議或者補(bǔ)充可以留言在文章下方,感謝大家的支持!
總結(jié)
以上是生活随笔為你收集整理的Java 设计模式 Day3 之面向抽象原则:什么是面向抽象编程?面向抽象编程如何应用?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 激活后蓝屏重启黑屏怎么办 电脑激活后出现
- 下一篇: 设置了共享打印机打印不了怎么办 共享打印