溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

編程語言中面向?qū)ο蟮慕榻B以及使用方法

發(fā)布時(shí)間:2021-06-25 10:06:48 來源:億速云 閱讀:148 作者:chen 欄目:大數(shù)據(jù)

這篇文章主要介紹“編程語言中面向?qū)ο蟮慕榻B以及使用方法”,在日常操作中,相信很多人在編程語言中面向?qū)ο蟮慕榻B以及使用方法問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”編程語言中面向?qū)ο蟮慕榻B以及使用方法”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

面向?qū)ο?/h3>
  1. 什么是面向?qū)ο?/p>

面向?qū)ο?Object Oriented)是軟件開發(fā)方法。面向?qū)ο蟮母拍詈蛻?yīng)用已超越了程序設(shè)計(jì)和軟件開發(fā),擴(kuò)展到如數(shù)據(jù)庫系統(tǒng)、交互式界面、應(yīng)用結(jié)構(gòu)、應(yīng)用平臺、分布式系統(tǒng)、網(wǎng)絡(luò)管理結(jié)構(gòu)、CAD技術(shù)、人工智能等領(lǐng)域。面向?qū)ο笫且环N對現(xiàn)實(shí)世界理解和抽象的方法,是計(jì)算機(jī)編程技術(shù)發(fā)展到一定階段后的產(chǎn)物。 面向?qū)ο笫窍鄬τ诿嫦蜻^程來講的,面向?qū)ο蠓椒?,把相關(guān)的數(shù)據(jù)和方法組織為一個(gè)整體來看待,從更高的層次來進(jìn)行系統(tǒng)建模,更貼近事物的自然運(yùn)行模式。 百度百科

依據(jù)以上解釋,初學(xué)者很難理解什么是面向?qū)ο螅蟾抛鰝€(gè)簡單解釋,因?yàn)槊嫦驅(qū)ο蟮母拍罘浅4?,所以大家有什么意見或建議請與我聯(lián)系。

  • 面向?qū)ο笫且粋€(gè)方法論,采用這種方法論,軟件開發(fā)人員能夠更好的進(jìn)行開發(fā)工作;

  • 面向?qū)ο笫菂^(qū)別于面向過程的一個(gè)方法論,關(guān)于面向過程請看第2點(diǎn);

  • Object的中文含義是“目標(biāo)”、“物體”等,面向?qū)ο?,即站在一個(gè)Object的角度去思考;

  • 面向?qū)ο蟮恼Z言都是高級語言,主流有Java\C++\Python\Objective-C\JavaScript\Python\PHP等(排名不分先后);

  • 在面向?qū)ο笾?,現(xiàn)實(shí)世界的一個(gè)事物即為一個(gè)對象,各自有其不同屬性(形狀\顏色等),不同行為(功能)。使用編程語言把這些屬性和行為描述成一個(gè)抽象的對象,且不同的編程語言有不同的表達(dá)方式。

  1. 面向過程

“面向過程”(Procedure Oriented)是一種以過程為中心的編程思想。這些都是以什么正在發(fā)生為主要目標(biāo)進(jìn)行編程,不同于面向?qū)ο蟮氖钦l在受影響。與面向?qū)ο竺黠@的不同就是封裝、繼承、類。百度百科

一、相關(guān)概念

1、對象

??有人說,女朋友/男朋友就是對象。顯然,這個(gè)說法是正確的。因?yàn)?,每個(gè)人都有一些屬性,比如:姓名、性別、身高、年齡、身份證號等等;也有一些行為,例如:走路、吃飯、工作等。
??萬事萬物都是一個(gè)對象,人們描述一個(gè)事物,經(jīng)常通過一些名稱、形狀和很多特征去描述,比如 是人、直立行走、會使用工具等,那么這個(gè)過程,是自然語言描述一個(gè)事物的過程,在面向?qū)ο缶幊讨?,同樣可以使用相似的語言描述成一個(gè)事物,那么這個(gè)事物代表人,以JavaScript代碼為例:
編程語言中面向?qū)ο蟮慕榻B以及使用方法
??女朋友是被丈母娘生下來的,那么編程中的對象,也是被創(chuàng)建出來的,以上方法就是在JavaScript中創(chuàng)建一個(gè)對象的過程。

面向?qū)ο缶幊蹋∣OP)

面向?qū)ο蟪绦蛟O(shè)計(jì)(Object Oriented Programming)作為一種新方法,其本質(zhì)是以建立模型體現(xiàn)出來的抽象思維過程和面向?qū)ο蟮姆椒āDP褪怯脕矸从超F(xiàn)實(shí)世界中事物特征的。任何一個(gè)模型都不可能反映客觀事物的一切具體特征,只能對事物特征和變化規(guī)律的一種抽象,且在它所涉及的范圍內(nèi)更普遍、更集中、更深刻地描述客體的特征。通過建立模型而達(dá)到的抽象是人們對客體認(rèn)識的深化。百度百科

??通俗來講,我們把現(xiàn)實(shí)世界的一個(gè)事物,使用編程語言描述成編程世界中的對象,然后再去使用這些對象進(jìn)行對更高一級世界的構(gòu)建的過程,就是面向?qū)ο缶幊獭?br/> ??我們描述出什么是學(xué)生,什么是老師,什么是課程,可以構(gòu)成一個(gè)課程管理系統(tǒng);同樣,我們描述出商品,描述出用戶,描述出訂單,可以構(gòu)成一個(gè)網(wǎng)上商城。

二、面向?qū)ο笕筇卣?/h3>
  1. 封裝

把一個(gè)對象的屬性和行為,封裝到一個(gè)不可分割的獨(dú)立實(shí)體,把自己可以被外界訪問的通過受保護(hù)的接口公開,即屬性私有,方法公開。

??上面的內(nèi)容太官方,封裝,用一臺電腦比喻,包含主板、CPU、內(nèi)存條、硬盤、顯卡等等,這些是不可被人直接去操作的。那么我們同樣能夠通過鍵盤、鼠標(biāo)、顯示器等輸入輸出設(shè)備去訪問操作這臺電腦。
??我們無法直接去訪問其被包起來的內(nèi)容,這些屬于電腦私有的,是不可以被訪問的,當(dāng)然我們可以通過輸入輸出設(shè)備去操作這臺電腦,這部分是對外開放的,你可以進(jìn)行訪問的。
??聽起來就像是電腦的外殼把它的核心組件給封裝了起來,然后通過一些插口來接入鍵盤鼠標(biāo),你進(jìn)行操作。沒錯(cuò),這就是封裝。

class Computer{
	String cpu;
	int memory;
	String gpu;
	String hardDisk
	
	public void powerOn(){
		//開機(jī)
	}
	public void powerOff(){
		//關(guān)機(jī)
	}
}
  1. 繼承

子類繼承父類,可以使得子類具有父類的方法和屬性,無需重寫父類的方法即可調(diào)用。子類同樣可以重寫父類的方法使得父類的方法具有不同的的功能。子類可以追加新的方法,使得子類的功能更豐富。

??雖然不是兒子繼承父親遺產(chǎn),但是同樣,兒子可以擁有父親的資產(chǎn)。子類繼承了父類,擁有父類的方法和屬性。
??在編程中的繼承,是因?yàn)槌橄蟮脑驅(qū)е碌?,比如,英語老師和數(shù)學(xué)老師,物理老師,都可以繼承 "老師" 這個(gè)父類,而老師,是在這個(gè)過程中屬于一個(gè)抽象的概念,那么三位老師都有教學(xué)的這個(gè)功能,同樣都有職業(yè)證書、職稱等等屬性。這個(gè)特性也會造成下一個(gè)面向?qū)ο蟮奶匦浴鄳B(tài)。
??但是不一樣的是,物理老師可以修電表,英語老師可以和外國人交流,數(shù)學(xué)老師同樣能用數(shù)學(xué)方法解決生活中的問題。顯然他們都是老師的情況下,每個(gè)老師也有自己的超能力。

class Teacher{
	String title;//職稱
	String subject;//所授課程
	void teach(){
		//教學(xué)
	}
}

class EnglishTeacher extends Teacher{
	
	private String englishLevel;//英語等級
	
	void teach(){
		System.out.println("I am teaching English")
	}
	void talkToForeigners(){
		//和外國人對話
	}

}
  1. 多態(tài)

不同對象對同一個(gè)操作可以做出不同的反應(yīng),產(chǎn)生不同的執(zhí)行結(jié)果??梢酝ㄟ^指向基類的指針,來調(diào)用實(shí)現(xiàn)派生類中的方法。

??老師都可以教學(xué),那么不同的老師,所教的內(nèi)容不一樣,數(shù)學(xué)老師教我們數(shù)學(xué),英語老師教我們英語,而物理老師教我們物理。
??此處我們當(dāng)然是需要調(diào)用父類(老師)的教學(xué)方法,但是因?yàn)椴煌淖宇愔貙懥烁割惖姆椒?,所以?dāng)通過調(diào)用父類的方法的時(shí)候,才會產(chǎn)生不同的結(jié)果。
??向上造型是產(chǎn)生多態(tài)的基石,比如我們可以這么寫 Teacher teacher = new MathTeacher() 來實(shí)現(xiàn)向上造型,此時(shí)我們調(diào)用 teacher.teach() 方法,則會調(diào)用到數(shù)學(xué)老師的 teach() 方法。

  1. 關(guān)于抽象

抽象是指從具體事物抽出、概括出它們共同的方面、本質(zhì)屬性與關(guān)系等,而將個(gè)別的、非本質(zhì)的方面、屬性與關(guān)系舍棄的思維過程。

??抽象并沒有被列到面向?qū)ο笕筇卣髦?,相對來說,個(gè)人認(rèn)為這個(gè)是面向?qū)ο蟮幕痉椒ǎ忻嫦驅(qū)ο蟮奶卣鞫蓟?,先進(jìn)行抽象,才能構(gòu)建出對象。
??我們在編程過程中會盡可能的使用抽象思維,將一個(gè)或者一類現(xiàn)實(shí)世界的事物,使用面向?qū)ο笳Z言,變成編程中的對象。
?? 比如剛才我們把三個(gè)不同的老師抽象成老師,事實(shí)上我們還可以把老師歸并到學(xué)校的工作人員,把學(xué)校工作人員歸并為社會工作人員,更可以把社會工作人員歸并為人類。當(dāng)然,越是抽象的對象,其屬性和方法就會更少,以為共同點(diǎn)更少了。

三、六個(gè)原則

  1. 開閉原則

開閉原則規(guī)定“軟件中的對象(類,模塊,函數(shù)等等)應(yīng)該對于擴(kuò)展是開放的,但是對于修改是封閉的”,這意味著一個(gè)實(shí)體是允許在不改變它的源代碼的前提下變更它的行為。該特性在產(chǎn)品化的環(huán)境中是特別有價(jià)值的,在這種環(huán)境中,改變源代碼需要代碼審查,單元測試以及諸如此類的用以確保產(chǎn)品使用質(zhì)量的過程。百度百科-開閉原則

應(yīng)該對于擴(kuò)展是開放的,但是對于修改是封閉的這句話不好理解,但是可以看一個(gè)例子:

/**
 * <p> mapper基類 </p>
 *
 * @author Calvin
 * @date 2019/11/07
 * @since
 */
public abstract class BaseMapper<BaseEntity>{

    /**
     * 新增或保存
     * @param entity
     */
    public void saveOrUpdate(BaseEntity entity){
        String id = entity.getId();
        BaseEntity exists = null;
        if(StringUtils.isNotEmpty(id) && (exists = this.findById(id)) == null){
            this.save(entity);
        }else{
            this.update(entity);
        }
    }

    /**
     * 根據(jù)ID查找,抽象方法
     * @param id
     * @return
     */
    abstract BaseEntity findById(String id);

    /**
     * 新增
     * @param entity
     */
    abstract void save(BaseEntity entity);

    /**
     * 修改
     * @param entity
     */
    abstract void update(BaseEntity entity);

}

通過定義一個(gè)baseMapper,以后有新增的Mapper中有saveOrUpdate方法,我們只需要令其實(shí)現(xiàn)BaseMapper, 使得 其對應(yīng)的Bean去繼承 BaseEntity,這樣我們就能夠橫向進(jìn)行擴(kuò)展。

class UserMapper extends BaseMappper{
    @Override
    public User findById(String id){
    // select * from user where id = #{id}
    }
    @Override
    public void save(User user){
    // insert into user ......
    }
    @Override
    public void update(User user){
    //update user set .... where id = #{user.id}
    }
}

另外有三點(diǎn)約束:

  • 第一,通過接口或者抽象類約束擴(kuò)展,對擴(kuò)展進(jìn)行邊界限定,不允許出現(xiàn)在接口或抽象類中不存在的public方法;

  • 第二,參數(shù)類型、引用對象盡量使用接口或者抽象類,而不是實(shí)現(xiàn)類;

  • 第三,抽象層盡量保持穩(wěn)定,一旦確定即不允許修改。
    找到一篇帖子,個(gè)人認(rèn)為是融會貫通了:https://www.liangzl.com/get-article-detail-133084.html

  1. 接口隔離

客戶端不應(yīng)該依賴它不需要的接口;一個(gè)類對另一個(gè)類的依賴應(yīng)該建立在最小的接口上。百度百科-接口隔離原則

也就是說,如果一個(gè)類,實(shí)現(xiàn)了一個(gè)擁有三個(gè)方法的接口,而這個(gè)類本身只需要使用其中兩個(gè),那么,此時(shí)違背了接口隔離的原則。

interface Interface1 {
    void function1();
    void function2();
    void function3();
}
class A implements Interface1{
    @Override
    public void function1(){
    //被需要的
    }
    @Override
    public void function2(){
    //被需要的
    }
    @Override
    public void function3(){
    //不被需要的
    }
}

此時(shí)需要對接口進(jìn)行改造,一般意義上是根據(jù)功能或者其領(lǐng)域,拆分成不同的接口。

interface Interface1 {

    void function1();

    void function2();
}
interface Interface2 {

    void function3();
}

拆分成兩個(gè)接口后,A類只實(shí)現(xiàn)Interface1,不需要實(shí)現(xiàn)Interface2,就可以了,代碼略,此時(shí)就算是簡單遵循了接口隔離。

接口隔離要注意的點(diǎn):

  • 接口要高內(nèi)聚。什么是高內(nèi)聚?高內(nèi)聚就是提高接口、類、模塊的處理能力,減少對外的交互,就比如一個(gè)人,你告訴下屬“到奧巴馬的辦公室偷一個(gè)XX文件”,然后就聽到下屬就堅(jiān)定的口吻回答你“好的,保證完成!”,然后一個(gè)月后還真的把XX文件放到你的辦公桌了,這種不講任何條件、立刻完成任務(wù)的行為就是高內(nèi)聚的表現(xiàn)。具體到接口隔離原則就是要求在接口中盡量少公布public方法,接口是對外的承諾,承諾越少對系統(tǒng)的開發(fā)越有利,變更的風(fēng)險(xiǎn)也就越少,同時(shí)也有利于降低成本。

  • 定制服務(wù)。一個(gè)系統(tǒng)或系統(tǒng)內(nèi)的模塊之間必然會有耦合,有耦合就要相互訪問的接口(并不一定就是Java中定義的Interface,也可能是一個(gè)類或者是單純的數(shù)據(jù)交換),我們設(shè)計(jì)時(shí)就需要給各個(gè)訪問者(也就是客戶端)定制服務(wù),什么是定制服務(wù)?單獨(dú)為一個(gè)個(gè)體提供優(yōu)良優(yōu)良的服務(wù)。我們在做系統(tǒng)設(shè)計(jì)時(shí)也需要考慮對系統(tǒng)之間或模塊之間的定義要采用定制服務(wù),采用定制服務(wù)就必然有一個(gè)要求就是:只提供訪問者需要的方法,只暴露給調(diào)用的類它需要的方法,它不需要的方法則隱藏起來。只有專注地為一個(gè)模塊提供定制服務(wù),才能建立最小的依賴關(guān)系。

  • 接口盡量小,但是要有限度。接口的設(shè)計(jì)粒度是越小系統(tǒng)越靈活,這是不爭的事實(shí),但是這就帶來成接口數(shù)量過多,使設(shè)計(jì)結(jié)構(gòu)的復(fù)雜化,開發(fā)難度增加,維護(hù)性降低,這不是一個(gè)項(xiàng)目或產(chǎn)品所期望看到的。所以一定要適度。

本部分轉(zhuǎn)載自:https://blog.csdn.net/u012361379/article/details/88101102

  1. 職責(zé)單一

它規(guī)定一個(gè)類應(yīng)該只有一個(gè)發(fā)生變化的原因。百度百科-單一職責(zé)原則

此處的一個(gè)類只能有一個(gè)發(fā)生變化的原因此處是指,由于業(yè)務(wù)場景等原因?qū)е碌淖兓?,而不是代碼運(yùn)行期間的變化。解釋略有一點(diǎn)含糊,導(dǎo)致筆者在很早之前對此不是特別懂。

class UserMapper{
    User findOne(String id){
        //TODO
    }
    User insertOne(User user){
        //TODO
    }
    void updateById(User user){
        //TODO
    }
    User generateUser(String username, String password){
         User user = new User();
         user.setId(UUID.generateUUID().toString());
         user.setUsername(username);
         user.setPassword(password);
         insertOne(user)
    }
}
  • 以上是一個(gè)反例,這個(gè)類當(dāng)中存在一個(gè)生成學(xué)生的方法,還有插入新增查詢的方法,生成學(xué)生的方法依賴于新增。

  • 此時(shí)無論是生成學(xué)生的方法發(fā)生變化,還是插入學(xué)生的方法發(fā)生變化,都可能導(dǎo)致另一個(gè)方法(以至于這個(gè)類)發(fā)生變化。

代碼進(jìn)行修改

class UserMapper{
	User findOne(String id){
		//TODO
	}
	User insertOne(User user){
		//TODO
	}
	void updateById(User user){
		//TODO
	}
}
class UserGenerator{
	UserMapper userMapper;
	
	UserGenerator(UserMapper userMapper){
		this.userMapper = userMapper;
	}
	
	User generateUser(String username, String password){
		User user = new User();
		user.setId(UUID.generateUUID().toString());
		user.setUsername(username);
		user.setPassword(password);
		userMapper.insertOne(user)
	}
}
  1. 里式替換

任何基類可以出現(xiàn)的地方,子類一定可以出現(xiàn)。 百度百科-里式替換原則

??里氏代換原則是很多其它設(shè)計(jì)模式的基礎(chǔ)。它和開放封閉原則的聯(lián)系尤其緊密。違背了里氏代換原則就一定不符合開放封閉原則。還是Teacher那個(gè)代碼:

public TeacherTest{

    public static void main(String [] args){
        Teacher teacher = new MathTeacher();
        teacher.teach();
        
        MathTeacher mathTeacher = new MathTeacher();
        mathTeacher.teach();
    }
}

??兩個(gè)測試方法執(zhí)行結(jié)果會完全一樣。

  • 一:子類可以實(shí)現(xiàn)父類的抽象方法,但是不能覆蓋父類的非抽象方法.【核心觀念】

  • 二:子類中可以增加自己特有的方法.

  • 三:前置條件放大,子類在重載父類的已實(shí)現(xiàn)方法時(shí),方法的前置條件(形參)范圍應(yīng)該比父類更加寬松.

  • 四:后置條件縮小,子類在實(shí)現(xiàn)父類的抽象方法時(shí),方法的后置條件(返回值)范圍應(yīng)該比父類更加嚴(yán)格或相同.

??此部分原文鏈接:https://blog.csdn.net/hongxiancheng/article/details/83049746

  1. 依賴倒置

程序要依賴于抽象接口,不要依賴于具體實(shí)現(xiàn)。高層次的模塊不應(yīng)該依賴低層次的模塊,二者應(yīng)該依賴其抽象;抽象不應(yīng)該依賴細(xì)節(jié);細(xì)節(jié)應(yīng)該依賴抽象。簡單的說就是要求對抽象進(jìn)行編程,不要對實(shí)現(xiàn)進(jìn)行編程,這樣就降低了客戶與實(shí)現(xiàn)模塊間的耦合。

有認(rèn)識過SpringMVC的人一定懂這個(gè):

public interface UserService{
    User create(HashMap args);
}

@Mapper
public interface UserMapper{
	void insert(User user);
}

public class UserServiceImpl implements UserService{
	
	@Autowride
	private UserMapper userMapper;
	
	public User create(HashMap args){
		User user = UserParser.fromMap(args);
		userMapper.insert(user);
	}
}

這就是典型的依賴倒置,調(diào)用方不用關(guān)心UserMapper具體實(shí)現(xiàn)是什么,只需依賴此接口,就能完成自己的業(yè)務(wù)邏輯。

  • 依賴倒置原則假定所有的具體類都是會變化的;

  • 為避免對類的直接調(diào)用,依賴倒置可能會使得項(xiàng)目產(chǎn)生更多的類;

  • 面向接口編程會使你更好的利用依賴倒置原則;

?
6. 迪特米法則

迪米特法則(Law of Demeter)又叫作最少知識原則(Least Knowledge Principle 簡寫LKP),就是說一個(gè)對象應(yīng)當(dāng)對其他對象有盡可能少的了解,不和陌生人說話。百度百科-迪特米法則

  • 一個(gè)女孩子

public class Girl{
	private BoyFriend boyFriend;
    public void getBoyFriend(){
		return this.boyFriend();
	}
}
  • 女孩的男朋友

public class BoyFriend{

	public void receiveMessage(String message){
		//response
	}
}
  • 女孩的閨蜜

public class BosomFriend{
	private Girl girl;
	BosomFriend(Girl girl){
		this.girl = girl;
	}
	public void talk(){
		String message = "I am so cold!";
		BoyFriend boyFriend = girl.getBoyFriend();
		boyFriend.receiveMessage(message);
	}
}

此時(shí),你的閨蜜直接告訴你男朋友的她很冷,顯然違背了迪特米法則,那么你應(yīng)該怎么做,以后他們的任何通信必須通過你。

public class Girl{
	private BoyFriend boyFriend;
	public void getBoyFriend(){
		return this.boyFriend();
	}
	//把你跟你男朋友說話的方法暴露出來
	public void talkToBoyFriend(String message){
		if(StringUtils.isNotEmpty(message)){
			//過濾一下說的什么內(nèi)容
			boyFriend.receiveMessage(message);
		}else{
			//當(dāng)然不能告訴男朋友了
		}
	}
}

以后他們交流就可以通過你交流,這樣避免他們私下里溝通。當(dāng)閨蜜類不再依賴男朋友類的時(shí)候,就遵從了迪特米原則。

public class BosomFriend{
	private Girl girl;
	BosomFriend(Girl girl){
		this.girl = girl;
	}
	public void talk(){
		String message = "I am so cold!";
		girl.talkToBoyFriend(message);
	}
}
  • 盡量減少對象之間的交互,從而減小類之間的耦合。簡言之,一定要做到:低耦合,高內(nèi)聚。

  • 在做系統(tǒng)設(shè)計(jì)時(shí),不要讓一個(gè)類依賴于太多的其他類,需盡量減小依賴關(guān)系。

四、總結(jié)

1、本文簡單介紹了面向?qū)ο蠛推浜诵母拍睿?br/> 2、簡單通過代碼,演示了面向?qū)ο蟮奶卣鳎?br/> 3、通過demo詳細(xì)介紹了面向?qū)ο蟮腟OLID五大原則和迪特米法則;

到此,關(guān)于“編程語言中面向?qū)ο蟮慕榻B以及使用方法”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI