我的發帖。
我的體會:
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#includeusing
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 抽象。用來限定類時,類中的方法不能有...