1樓:vs王仁輝
student是person的子類,那麼student和person都可以看成person型別,物件型別和物件實體要分清楚。1.person p1=new person();這種建立的是父類物件,呼叫方法和屬性都是person類的;2.
person p2=new student();這種建立的是子類物件,呼叫方法和屬性都是student類的,person就像一個姓,具體的名字都是自己的,和別人無關,姓都一樣,但是你new誰就是誰的物件
2樓:哈魯擼啊擼
person p = new student();
j**a中父類物件引用指向子類物件
j**a裡面的向上造型中,父類引用指向子類物件時,父類引用只能訪問父類的方法,變數等
定義一個父類型別的引用指向一個子類的物件有什麼用
3樓:匿名使用者
1.從物件的記憶體角度來理解.
假設現在有一個父類father,它裡面的變數需要佔用1m記憶體.有一個它的子類son,裡面的變數需要佔用0.5m記憶體.
現在通過**來看看記憶體的分配情況:
2.f = new father();//系統將分配1m記憶體.
son s = new son();//系統將分配1.5m記憶體!因為子類中有一個隱藏的引用super會指向父類例項,所以在例項化子類之前會先例項化一個父類,也就是說會先執行父類的建構函式.
由於s中包含了父類的例項,所以s可以呼叫父類的方法.
3.son s1 = s;//s1指向那1.5m的記憶體.
father f1 = (father)s;//這時f1會指向那1.5m記憶體中的1m記憶體,即是說,f1只是指向了s中例項的父類例項物件,所以f1只能呼叫父類的方法(儲存在1m記憶體中),而不能呼叫子類的方法(儲存在0.5m記憶體中).
son s2 = (son)f;//這句**執行時會報classcastexception.因為f中只有1m記憶體,而子類的引用都必須要有1.5m的記憶體,所以無法轉換.
son s3 = (son)f1;//這句可以通過執行,這時s3指向那1.5m的記憶體.由於f1是由s轉換過來的,所以它是有1.5m的記憶體的,只是它指向的只有1m記憶體.
4.static
顧名思義,就是靜態的,他是方法的,他屬於這個類,由於是類的方法,他可以直接引用類名來引用方法,也可以通過類的物件來引用這個方法,他既不能被子類覆
蓋,也不能被子類繼承。簡單的說,他是在編譯的時候就和類幫定在一起了,不能被執行時動態載入。
對子類與父類的static問題
——沒覆蓋也沒繼承,子類存有指向父類的引用
對於private
——該方法或屬性只能在該類內使用
c#中父類引用指向子類物件問題深究:
4樓:草薙在
哈哈,你想知道底層的東西麼?那我就告訴你,在底層中,一個變數是有型別的,而一個物件呢,也差不多算有型別的,在進行變數賦值的時候,clr會檢查是否可以允許賦值,如果是子類賦值給父類,或者子類給所實現介面類賦值的話,就可以。
當使用父類變數實際操作子類的時候,賦值欄位其實在底層上和直接操作子類變數沒區別,而呼叫方法則會使用callvirtual呼叫,這樣clr會根據實際情況呼叫父類或者子類方法(這情況講起來挺複雜的)
想徹底的瞭解這個東西,你需要學的還很多很多很多,我都是學了將近兩年才逐漸理解的,彆著急,慢慢來。
回答補充:
這就是說,其實物件在記憶體中是不會考慮什麼型別的,他有什麼欄位就是有什麼欄位,但是物件型別和變數型別是兩碼事,你不敢保證你的變數擁有什麼別的方法,比如汽車類,那麼轎車物件和卡車物件都可以賦給汽車的變數,但是你在寫**的時候敢保證他一定就是卡車,一定就有載貨這個方法麼?也許你敢保證,但是c#編譯器不敢,所以點不出來
我建議你學學反射,會讓你知道其實物件不管賦給什麼型別的變數,其實本身沒有變化,都是那個物件,只不過你看到的,你能用到的,所謂的廣義的介面,是不同的。
5樓:匿名使用者
其實父類引用指向子類的時候,只要稍作除錯就會知道是怎麼回事。
第一父類物件引用子類的時候父類物件只是一個說明,而真正例項化得則是子類物件,這就好比經紀人和歌手的關係,經紀人接到命令,真正幹活的是歌手一樣
6樓:匿名使用者
好抽象啊,大哥給個程式啊。
7樓:
【當用父類引用進行“.”操作的時候只能顯示出來父類的欄位值(也就是儲存在記憶體中子類物件的值),這樣理解對嗎?】
不對,父類引用子類的例項,其實這個物件屬於子類的型別,但編譯器會誤認為這個物件是父類的型別(因為編譯器只看它的申明型別),所以“.”操作仍然會呼叫父類的方法和屬性,這一過程在編譯時就已經完成了繫結,
但是如果這個方法是虛方法(用virtual修飾),情況就不一樣了,編譯的時候clr如果判斷該方法是虛方法,就會等到執行時才去晚繫結,所以在執行時這個型別該是什麼型別就會呼叫相應的方法,
8樓:匿名使用者
你的問題非常的好。
你加進集合中的的確是子類的例項,關鍵是你用什麼型別的引用指向這個子類的例項。關於你呼叫子類的屬性或者方法是要和它的引用型別吻合的,並不是子類例項的所有東西都一定能夠呼叫到。這個是物件導向的一個重要的特性。
舉個例子:
介面ia裡有方法: fa()
介面ib裡有方法: fb()
子類c實現(繼承)了介面ia,ib,並且子類自己定義了個方法fc(),則子類c就有:fa(),fb(),fc()三個方法
當子類c的例項objc被ia型別的引用指向的時候[ia objc = new c()或者(ia)objc],你可以呼叫到的是fa(),通俗的說objc這裡是ia型別的,而並不是c型別的,所以只能調ia的fa()
當子類c的例項objc被ib型別的引用指向的時候[ib objc = new c()或者(ib)objc],你可以呼叫到的是fb(),通俗的說objc這裡是ia型別的,而並不是c型別的,所以只能調ib的fb()
當子類c的例項objc被c型別的引用指向的時候[c objc = new c()或者(c)objc],你可以呼叫到的是fa(),fb(),fc()
這個其實就是面向介面或者說是物件導向程式設計的一個內容
j**a父類引用指向子類的物件是什麼意思?
ai中如何在已經建立的畫布旁邊再建立畫布
浪小客 1 滑鼠選擇單擊開啟adobe illustrator cc 2015版軟體。2 在選單欄中選擇檔案選項卡里的新建選項單擊一下。3 彈出對話方塊,根據需要調整大小,然後確認。4 單擊工具欄上的畫板工具,繼續重複動作,可以建立多個畫板。4 然後將滑鼠移動到帶有虛線框的畫板上,按住alt和滑鼠左...
php,子類無法訪問父類私有屬性,子類例項化再賦值後,子類所新增的新成員屬性不存在
這兩句沒問題 student1 dance student1 say 問題出在這三句 student1 name zhangsan student1 age 20 student1 gender male 這三個都是私有成員,不能直接賦值,可以在基類中實現公共的set方法或者建構函式來賦值。 隋龍飛...
建立堆疊類C,建立乙個堆疊類模板 C
五十子 寫完再來貼 我覺得鏈棧沒必要初始化,建構函式已經夠了,更不必判棧滿,所以就沒寫。若非要的話,發信給我,再幫你寫乙個初始化函式template class stack x base,top public stack stack void inti void push t t pop int e...