子類繼承父類的虛擬函式呼叫
父類:Father
子類:Son
1. Father* fa=new Son()
例項1:
執行結果:#include<iostream> using namespace std; class Father{ public: Father(){ cout << "this is the Father constructor!" << endl; } void watchTv(){ cout << "Father is watching tv!" << endl; } virtual void say(){ cout << "Father is saying!" << endl; } }; class Son :public Father{ public: Son(){ cout << "this is the Son constructor!" << endl; } void watchTv(){ cout << "Son is watching tv!" << endl; } void say(){ cout << "Son is saying!" << endl; } }; int main(){ Father* fa = new Son(); fa->watchTv(); fa->say(); system("pause"); return 0; }
結果分析:
1.首先執行程式碼 Father* fa=new Son();,會首先呼叫父類建構函式,再呼叫子類建構函式,所以第一、第二行如圖所示;
2.執行程式碼fa->watchTv(),根據fa的型別,因為是Father型別的,所以會先檢視Father類中的watchTv函式,因為不是虛擬函式,所以直接呼叫,結果如第三行所示;
3.執行程式碼fa->say(),根據fa的型別,因為是Father型別的,所以先檢視Father類中的say函式,因為是虛擬函式,所以會檢視虛擬函式表,檢視實現例項,找到子類Son有實現虛擬函式say,所以會呼叫子類Son的say函式,結果如第四行所示。
例項2: 在建構函式中呼叫虛擬函式
#include<iostream> #include<string> using namespace std; class Father{ public: Father():val("HunanTv"){ cout << "this is the Father constructor!" << endl; say(); } virtual void watchTv(){ cout << "Father is watching tv:" <<val<< endl; } void say(){ cout << "Father is saying to watchTv!" << endl; watchTv(); } string val; }; class Son :public Father{ public: Son(){ cout << "this is the Son constructor!" << endl; say(); } virtual void watchTv(){ val = "GuangdongTv"; cout << "Son is watching tv:"<<val << endl; } }; int main(){ Father* fa = new Son(); fa->say(); system("pause"); return 0; }
執行結果:
結果分析:
1.執行程式碼Father* fa=new Son(),會先呼叫父類建構函式,父類建構函式中會執行以下操作:a)首先給變數val賦值為“HunanTv",其次,呼叫函式say(),此時會輸出前兩行內容;b)因為say()函式會呼叫虛擬函式watchTv(),而且在子類中有watchTv的例項實現,但是根據輸出結果第三行發現,呼叫的還是父類的虛擬函式,為什麼呢?因為,父類建構函式中呼叫虛擬函式,表現的虛擬函式為父類的虛擬函式,所以結果為第三行的顯示;c)父類建構函式呼叫完後,執行子類建構函式,因為子類沒有定義say()函式,所以呼叫繼承自父類的say()函式,所以輸出結果為第四、第五行;d)say函式呼叫虛擬函式watchTv(),因為是在子類Son的建構函式中呼叫虛擬函式,所以呼叫的是子類的watchTv,所以輸出結果如第六行所示;e)執行完子類構建後,執行fa->say();,首先看fa的型別,所以呼叫父類的say(),say()呼叫虛擬函式watchTv時,因為watchTv在子類中有例項實現,所以會呼叫子類的watchTv,所以輸出結果如第七、第八行所示。
總結:
1.當在建構函式中呼叫虛擬函式時,虛擬函式表現為該類中虛擬函式的行為,即父類建構函式呼叫虛擬函式,則虛擬函式為父類中的虛擬函式;子類建構函式中呼叫虛擬函式,則呼叫的是子類中的虛擬函式;
2.如果不是在建構函式中呼叫虛擬函式,則會首先檢視虛擬函式表,如果有例項實現,則呼叫例項。比如:父類中有虛擬函式watchTv,則呼叫父類中watchTv時,則因為子類實現了watchTv,則呼叫子類的watchTv。
相關推薦
子類繼承父類的虛擬函式呼叫
父類:Father 子類:Son 1. Father* fa=new Son() 例項1: #include<iostream> using namespace std; class Father{ public: Father(){ cou
c++子類繼承父類函式呼叫特性原理以及與java的對比
c++ c++中子類繼承了父類,子類物件的函式和變數會接著新增在父類物件的記憶體後面,以此類推。。。 如果c++中父類的那個變數或者函式宣告為virtual虛擬函式,那麼子類物件的同名函式就直接覆蓋了(即在記憶體中真正的覆蓋,父類的這個函式已經不在了)父類物件的這個函式 如
關於子類繼承父類後呼叫方法的問題
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class ParentClass { public String m
子類繼承父類,重寫父類方法,運用多型時呼叫重寫的方法時呼叫子類的還是呼叫父類的?
package 第五天; public class Person { public void say() { System.out.println("我是Person的say方法"); } } 子類Student如下: package 第五天; publ
Java子類繼承父類並呼叫介面
父類程式碼: 功能:定義一個vehicle類及其中的set函式及get函式 public class vehicle { private double speed; private String name; private String color; publi
子類繼承父類後想要擴展父類方法
保留 回調 gen obj pcl logs col 父類 sel 1 >>> class PClass(object): 2 def setInfo(self,sex=‘Male‘): 3 self.gender = se
Java 子類繼承父類成員中的問題
subclass 情況 討論 就會 之前 測試 public 測試結果 string 之前搞錯了,變量沒有“重寫”一說,只有方法才能被“重寫”。如果我們在子類中聲明了一個和父類中一樣的變量,那麽實際的情況是,子類的內存堆中會有類型和名字都相同的兩個變量。 現在考慮一
python 子類繼承父類__init__(轉載)
elf lpad pla 最好 就是 main 代碼 borde wid 轉載: http://www.jb51.net/article/100195.htm 前言 使用Python寫過面向對象的代碼的同學,可能對 __init__ 方法已經非常熟悉了,__init__
子類繼承父類,父類中的構造器
gen 向上轉型 類構造 復制 使用 article col 成員 ring 子類繼承父類,子類構造器會默認調用super()(無論構造器中是否寫有super()),用於初始化父類成員.同時當父類中存在有參構造器時,必須提供無參構造器,子類構造器中並不會自動繼承有參構造器,
Java子類繼承父類,類的載入順序,看著一篇就夠了
1. 程式碼 package parent; public class Child extends Father { static { System.out.println("
java中的繼承-子類繼承父類的許可權問題
java中的繼承 Java語言面向物件有三大特性:封裝、繼承、多型。其中的繼承,描述了一
java中子類繼承父類呼叫利用繼承方法時呼叫this
package cn.itcast.test1; class Parent{ public Object getObject(){ return this; } } c
python 子類繼承父類的__init__方法
父類: 1 class A(object): 2 def __init__(self, name): 3 self.name = name 4 print("父類name:", self.name) 5 6 def getName(self): 7
java中子類繼承父類時是否繼承建構函式呢?
java繼承中對建構函式是不繼承的。 以下是例子: public class FatherClass { public FatherClass() { System.out.println(100); } public FatherClass(int age)
子類繼承父類的輸出結果
public class A { static{ System.out.println("static in class A"); } public A(){ System.out.println("class A"); }
JAVA基礎-子類繼承父類例項化物件過程
class Parent { // 靜態變數 public static String p_StaticField = "父類--靜態變數"; // 變數(其實這用物件更好能體同這一點,如專門寫一個類的例項) //如果這個變數放在初始化塊的後面,是會報錯的,因為你根本沒
子類繼承父類,new 一個子類物件的過程(待完善)
父類 public class JVMBase { public static String staticName="父類靜態變數"; public String name="父類非靜
java中序列化之子類繼承父類序列化
當一個父類實現Serializable介面後,他的子類都將自動的實現序列化。 以下驗證了這一點: package Serial; import java.io.Serializable; public class SuperC implements Serializable {//父類實現了序列化
父類實現Parcelable介面,子類繼承父類需要實現的操作
show me the code public class A implements Parcelable { public String str; public boolea
關於學習Kotlin子類繼承父類,成員屬性Override時候需要注意的問題
最近在學習Kotlin這門語言,作為一個java程式設計師兼android程式設計師,Kotlin又在17年強勢被google推崇為android官方開發語言之一,這就意味著,過去基於java語言的android開發人員,很有必要去掌握Kotlin這門語言,當然我這裡不去談論