對繼承的理解。

2022-03-13 16:41:22 字數 3170 閱讀 6804

我的發帖。

我的體會:

0) 在做前端的時候發現乙個繼承的適合場景,就是母模板和子頁面的關係。用繼承比組合恰當。

1) 繼承的根本目的是為了對要解決的問題進行更好的建模

2)繼承的目的不是復用,從某種意義上來說,恰恰是為了處理不能復用的場景。所以才有繼承。復用只是大多數優秀模型的乙個必然結果而已。

3)從底層實現來說,就是把原來乙個含判斷多分支的函式,根據判斷分開放到不同的方法**區塊,但使用同乙個函式名稱。

4)繼承而不是用引數來擴充套件,從某種意義上來說,就是符合了開閉原則,只有對專案有要求,才會知道開閉原則的重要,引數畢竟不能無限考慮到後期擴充套件。

這樣,當有以新方法時新增時,不用新增到原來大一統的函式裡。而放到另外乙個i**區塊(新建立乙個派生類)。對修改關閉。

4)很多情況組合會好過繼承。不是繼承不好,而是has-a關係很容易誤認為is-a關係(語言習慣問題,等等)。如,小明是乙個工程師。看起來是is-a。其實正確的說法是,小明是乙個含有工程師工作的人。明顯的2個抽象物件。人和職業。

工程師對於人來說並不是絕對穩定的。人可以變換工作。但是對於職業來說卻是穩定的。工程師天生就是一種職業。

5)建模過程需要一組類實現更高的抽象,那麼使用多型。但注意要把抽象精小化。這樣可以使一組類包含乙個抽象,而不是整組類都實現此抽象。來達到更低的耦合。

6)最近感覺繼承中的基類,根本不應該有private。基類就應該純虛類或者帶protect資料。要不private資料到底什麼意思?基類設定private資料的情況自己還沒碰到過。

c++真的必須閹割才能安全使用。

還有一篇,感覺寫的很好的文章。

從軟體的發展過程來解釋繼承。當前都是分層開發,資料庫都是關係型資料庫。表與表之間基本都是互動關係。而不是繼承關係。所以繼承的使用,當前來說,很少是匹配適用的。

除非是的is a關係。絕大多數都用組合或其他模式吧。

看 程式設計規範 一書中

37條款。

再一次印證了繼承不是為了重用。

一直在想如何正確使用is-a,書中給了非常正確的解釋,不要解讀為是乙個。要解讀為 行為像乙個。 比如下面的例子。

銷售,工程師,和職工,不能說小張是乙個工程師。就用繼承,而應該說 小張的行為像乙個工程師。明顯小張的行為像乙個工程師是乙個錯誤的語義,小張行為像乙個人。而不是工程師。

#include#include 

using

namespace

std;

//1)新類和原類,計算工資不同,但為了新類和原類統一行為.建立基類,並設定為虛方法,為多型準備.

//2)修改原類為派生類,新加乙個派生類.

//並把我們認為實際中,確實是公有並且固定的方法(不會因為派生類不同而有所不同,並且預知以後也不可能會有多型行為),設定為實方法.提供公用.

//3)因此我們的目的是為了統一行為,手段是繼承和虛方法,最終多寫了**,增加了複雜度,但安慰獎是,新加類可以復用基類的實方法.

//因此,繼承的**之一是不同類有不同行為,但要達到統一的目的,使用了多型的技術,復用是安慰獎.復用不是目的!!!

//繼續變動.如果乙個員工從saler變成了provider呢?sales linson("linson",20000,50000);改為provider linson("linson",20000);

//但是如果很多地方使用了這條sales linson("linson",20000,50000)語句呢.乙個乙個改.但總歸還是怕會有遺漏的.不是乙個好的解決問題方案.

//是否有更好的處理方法.首先想到,應該就是如何把計算工資的方法,和物件分離出來.但一想.員工型別你沒變過來啊.員工型別和工資分離.那我要員工型別做什麼?

//進而懷疑.我要繼承做什麼?

//這裡是否不應該用繼承?但是很明顯,毫無壓力的is-a關係啊.對,類和類之間確實是毫無爭議的is-a關係.

//但是派生類的物件.存在轉變為另外派生類物件的可能.這導致了毫無爭議的繼承場景,變成了讓人犯嘀咕的物件.

class

iworker

;void iworker::showsalary(ostream&os)

inline

string

iworker::getname()

iworker::iworker(

const

string&_name):name(_name){}

iworker::~iworker(){}

class sales:public

iworker

;int

sales::salary()

sales::sales(

const

string& _name,int _base,int

sum):iworker(_name),basesalary(_base),salesum(sum){}

class provider:public

iworker

;int

provider::salary()

provider::provider(

const

string& _name,int

_base):iworker(_name),basesalary(_base){}

//容器與繼承.

//多型,就必須使用指標,而不是物件.

//容器放指標的話.就會面臨指標所指物件是否存在的問題.

//所以如果不用堆記憶體,而是棧記憶體,也就是函式內不用new,那麼就必須保證,使用容器的作用域處於建立物件的作用域的層級之下.

//不能平級,更不能之上.一句話就是,使用容器的時候,容器中物件的棧,還沒有彈出.

//所以自己總結,安全的就是在主函式中.建立物件.主函式不到程式結束,是不可能會出棧的.即避免了new管理記憶體,又避免了物件的丟失.

//就是不能大資料.要不棧溢位.

//能不能做乙個深copy的容器.這樣就解決問題了啊.

void showworks(const vector&workers_vecotr);

class

singlefactory

;vector

createworks();

intmain()

void showworks(const vector&workers_vecotr)

}

對繼承對映的理解

繼承關係的對映策略有三種 每個繼承結構一張表 table per class hierarchy 不管多少個子類都用一張表。每個子類一張表 table per subclass 公共資訊放一張表,特有資訊放單獨的表。每個具體類一張表 table per concrete class 有多少個子類就有...

對C 繼承的理解

繼承是一種 復用的方式,使得我們不必寫重複的 例如,有三種怪物a b c,他們都有速度 血量 攻擊力 防禦值 攻擊方式。如果沒有繼承我們可能要寫三個指令碼monstera monsterb monsterc,而且在某個指令碼中我們還要重複的宣告定義變數speed等。如果這有三種怪物,那麼貼上複製起來...

對C 繼承的理解

繼承是可用傳遞的 子類是對父類的擴充套件 必須繼承父類的方法,同時在子類中新增新方法。子類可用呼叫父類的公用方法和字段 而父類不能呼叫子類的成員。子類不僅繼承了父類的共有成員 同時也繼承了父類的私有成員 只是在子類中不能被訪問。繼承的三個關鍵字 abstract 抽象。用來限定類時,類中的方法不能有...