1樓:殺退江湖
我給你說下c#繼承發生的一些事情吧,或許你自己就能理解為什麼會這樣了。
classb b = new classb();這句話會發生如下操作:
(1)計算 b所需要的記憶體空間,並分配這些空間。很明顯,這個記憶體空間除了要儲存c#本身的一些東西外,重點來分析對於繼承的類classb而言,它需要分配哪些空間。最重要的,你需要明白分配的記憶體空間只包含例項字段。
(方法等其他東西是和具體的物件例項無關的,方法只是一段**呼叫而已,這個你明白c++的話,應該很好理解資料合方法的區別吧。)
對於classb而言,它首先要分配的就是是繼承了classa的例項欄位s,然後分分配classb本身的字段,s,但是注意,兩個同名s的字段會導致覆蓋,也就是classb的字段會覆蓋本來已經從a繼承的s,所以此時,b物件的記憶體裡只有乙個s。當然,目前這個s為空。但必須明白它只有乙個s。
(2)初始化這段記憶體空間,也就是建立物件b。你這裡沒有呼叫自定義的建構函式(你也沒有定義),所以c#會呼叫預設的,預設的會幹嘛呢?
①,先初始化父類,也就是先會呼叫classa的預設建構函式,但務必注意,這裡並沒有出現乙個新的classa物件(具體細節需要的話,你追問我。)。這裡他會把"classa"賦值給s。
到這裡就完成了父類即classa的預設建構函式的呼叫(我說的是呼叫classa建構函式,但我沒說是例項化classa。主要這兩者的區別)。
②呼叫本身的建構函式,同樣是預設的,它會把"classb"賦值給s欄位,到這裡,s已經變成"classb"了。
(3)把這段記憶體空間指向變數b,classb b = new classb();執行完畢。
對應方法:
public override void show()
到b.show();這裡就很好理解了。
首先呼叫base.show()。注意,你需要理解這個base表示的是呼叫父類的方法而已,但是並沒有父類的例項也就是沒有新的classa物件產生。
實際上,因為b是繼承自a的,所以c#是完全認可b物件就是classa的乙個例項化物件(但你需要明白,在這種意義上,它自包含classa本身所定義的東西)。所以
public virtual void show()
這段**裡,this其實就是例項化的物件b而已,只是此時它只能訪問classa定義的東西而已。所以this.s會是「classb」。
而且我沒猜錯的話,此時的this.gettype同樣顯示的是classb,而不是classa。因為很好理解,b真正的型別是classb。
然後就是執行classb裡的方法console.writeline(this.s),這裡的this同樣是指向b物件的,但此時已經是徹底的b物件了,可以訪問b物件裡的所有東西了。
說了這麼多,這段過程是重點你要能理解this,並不是指向this所在的類的,因為this是和例項即物件相關,this指向的是物件。但是c#的多型允許子類的例項作為父類的引用,
比如:class b=new classb();classa a=b;
我相信這段**你比較容易理解,同樣,在你的方法呼叫裡 ,classa裡的this指向的是b這個物件,和classa a=new classb()的道理是一樣的。
呵呵,說了這麼多,不知道我說明白了多少,也不知道你理解了多少。因為對於c#的多型,clr內部實現是有很多過程來完成的。而這些不是這幾百字能搞定的。
有啥疑問就追問吧。不過我過年不會上網的。
如果你對c#的底層感興趣的,我推薦你讀讀clr via c#,然後讀讀《你必須知道的.net》好像是叫著名字,對理解clr很有幫助。
2樓:匿名使用者
classb中的show()方法不應該重寫基類的show()方法。應該將classb中的show()方法的定義這樣改:
public new void show() //不重寫,而是覆蓋基類的show()方法。
希望對你有幫助!
3樓:小妻丐
虛方法中 系統會預設個 隱試建構函式 public classa(){} 父類的方法可以被子類重寫,也可以不重寫。你在子類show方法中呼叫父類show方法沒必要 直接由建構函式傳參就可以 不必要再 子類和父類中單獨定義字段 建構函式可以使有引數的 也可以是無參建構函式 string s=「classa」;可以通過有參建構函式傳遞
c# 子類繼承了父類的private欄位或方法嗎?
4樓:
私有的是不能繼bai承過來du
了不太清楚,不能zhi訪問是確定的,此外繼承
dao的東西和父類肯定不內是乙個空間的,類容的定義是不分配空間的,只有類的實現時分配各自的空間,肯定不會和父類的重合的,子類實現和父類的實現都是各地單獨的空間。
5樓:
私有成員是會被父類整合的,除非是密封的方法活著屬性。題主不妨自己寫乙個私有字段,然後用乙個公開屬性封裝他,讓子類繼承這個公開屬性,然後你會發現你可以通過這個公開屬性修改那個你繼承來的私有欄位喔~
6樓:匿名使用者
在copyc#中,子類不能繼承
父類中用private修飾的成員變數和成員方法。
c#中的繼承:
(1)c#中,派生類只能從乙個類中繼承;派生類從它的直接基類中繼承成員:方法、域、屬性、事件、索引指示器。除了建構函式和析構函式,派生類隱式地繼承了直接基類的所有成員。
(2)c#中的繼承規則
1、繼承是可傳遞的。如果c從b中派生,b又從a中派生,那麼c不僅繼承了b中宣告的成員,同樣也繼承了a中的成員。object 類作為所有類的基類。
2、派生類應當是對基類的擴充套件。派生類可以新增新的成員,但不能除去已經繼承的成員的定義。
3、建構函式和析構函式不能被繼承。除此以外的其它成員,不論對它們定義了怎樣的訪問方式,都能被繼承。基類中成員的訪問方式只能決定派生類能否訪問它們。
4、派生類如果定義了與繼承而來的成員同名的新成員,就可以覆蓋已繼承的成員。但這並不因為這派生類刪除了這些成員,只是不能再訪問這些成員。
5、類可以定義虛方法、虛屬性以及虛索引指示器,它的派生類能夠過載這些成員,從而實現類可以展示出多型性。
6、派生類只能從乙個類中繼承,可以通過介面實現多重繼承。
(3)訪問與隱藏基類成員
7樓:匿名使用者
不能訪問只是在子bai類的du函式成
員中不能訪問,但是在zhi父類的函dao數成員中可以訪問,而這些函回數成員答可以繼承給子類,子類就可以間接訪問paivate了!另外通過base(),一樣的道理,也可間接操作父類的private成員,不信你試試!
8樓:匿名使用者
private修飾的是私有成員變bai
量的du,也就是只能本類使用
zhi,父類的private欄位只能dao父類自己使用protected修飾的是專保護型別成員變數,屬也就是繼承的子類也可以使用,父類的
protected欄位可以再父類和他的子類中使用public修飾的是公用成員變數,父類的public欄位,可以在其他類中使用,不管是不是這個父類的子類
9樓:我不發財
private是繼承不下來的。它只能在類內使用。繼承後沒有該方法與字段如果想繼承出啦可以使用公開的public。
10樓:匿名使用者
private欄位或方法只能在其本身的class中操作,不能被繼承
11樓:匿名使用者
private只能在類的本身裡呼叫,子類繼承不過來的,可以繼承public,protected,protected internal
12樓:匿名使用者
如果定義的類是private的好像只是在父類中使用吧,至於繼承好像沒有的!不然的話應該可以呼叫的!
13樓:匿名使用者
除了構造方法 析構方法,子類可以繼承到父類的所有成員.即使private成員,但子類無法直接訪問private成員
在c#中,子類不能繼承父類中用什麼修飾的成員變數和成員方法?
14樓:
1、關於私有成員變數
無論父類中的成員變數是私有的
、共有的、還是其它型別的,子類都會擁有父類中的這些成員變數。但是父類中的私有成員變數,無法在子類中直接訪問,必須通過從父類中繼承得到的protected、public方法(如getter、setter方法)來訪問。
2、關於靜態成員變數
無論父類中的成員變數是靜態的、還是非靜態的,子類都會擁有父類中的這些成員變數。
3、關於被子類覆蓋的成員變數
無論父類中的成員變數是否被子類覆蓋,子類都會擁有父類中的這些成員變數。
c 繼承問題
陽光下的月色 派生類的三種繼承方式小結 公有繼承public 私有繼承 private 和保護繼承 protected 是常用的三種繼承方式。1 對於公有繼承方式 基類成員對其物件的可見性與一般類及其物件的可見性相同,公有成員可見,其他成員不可見。這裡保護成員與私有成員相同。基類成員對派生類的可見性...
c虛擬函式如何調父類而非子類
1,如果以一個基礎類指標指向一個衍生類物件 派生類物件 那麼經由該指標只能訪問基礎類定義的函式 靜態聯翩 2,如果以一個衍生類指標指向一個基礎類物件,必須先做強制轉型動作 explicit cast 這種做法很危險,也不符合生活習慣,在程式設計上也會給程式設計師帶來困擾。一般不會這麼去定義 3,如果...
C類的問題
a pa1,pa2 定義了兩個a類的指標pa1,pa2可以呼叫類a的所有方法,換句話說,他們就是類a的例項化。pa1 new a 3.0,5.0 初始化pa1,這時候會呼叫類a的建構函式a float a,float b 也就是說,在pa1這個指向類a的例項中,成員變數x 3,y 5相當於初始化賦值...