Defined in base class and redefined in derived class.
使用pointer或reference存取derived class物件時,且pointer指向的類型是 base class 時才有此效果
dynamic binding or late binding
使用pointer或reference存取derived class物件時,且pointer指向的類型是 base class
如果衍生類別覆蓋了基礎類別中的method,通過上述指標或參照呼叫該方法時,可以有兩種結果:
呼叫到基礎類別的方法:編譯器根據指標或參照的類型決定,稱作 early binding
呼叫到衍生類別的方法:執行時系統根據物件的實際類型決定,稱作 dynamic binding or late binding
early binding
首先使用指針建立物件
#include <iostream>
using namespace std;
class Student{
public:
void Hello(){
cout << "I'm a student.\n";
}
};
class ChemsitryStudent : public Student{
public:
void Hello(){
cout << "I'm a student major in chemistry.\n";
}
};
int main()
{
Student *p_Amy = new ChemsitryStudent;
p_Amy -> Hello();
}
class Student{
public:
virtual void Hello(){ //add virtual
cout << "I'm a student.\n";
}
};
第一種情況derived class 有 implement
class ChemsitryStudent : public Student{
public:
void Hello(){
cout << "I'm a student major in chemistry.\n";
}
};
int main()
{
Student *p_Amy = new ChemsitryStudent;
p_Amy -> Hello();
}
此時程式執行時會連到ChemsitryStudent的Hello()
output
I'm a student major in chemistry.
第二種情況derived class 沒有 implement
class ChemsitryStudent : public Student{
public:
};
int main()
{
Student *p_Amy = new ChemsitryStudent;
p_Amy -> Hello();
}
class Student{
public:
virtual void Hello() = 0 ;
};
class ChemsitryStudent : public Student{
public:
void Hello(){
cout << "I'm a student major in chemistry.\n";
}
};
int main()
{
Student *p_Amy = new ChemsitryStudent;
p_Amy -> Hello();
}
class Student{
public:
virtual void Hello() = 0 ;
};
class MathStudent : public Student{
public:
void Hello(){
cout << "I'm a student major in Math.\n";
}
};
class ChemsitryStudent : public Student{
public:
void Hello(){
cout << "I'm a student major in chemistry.\n";
}
};
int main()
{
Student *p_Amy = new MathStudent;
Student *p_Jim = new ChemsitryStudent;
Student *p_Name[]={p_Amy,p_Jim};
for(int i = 0 ; i <=2 ; i++){
p_Name[i] -> Hello();
}
}
雖然pointer皆指向 Student 這個class,但是表現出來的method不同
I'm a student major in Math.
I'm a student major in chemistry.
Virtual Function
base class
時才有此效果使用pointer或reference存取derived class物件時,且pointer指向的類型是 base class 如果衍生類別覆蓋了基礎類別中的method,通過上述指標或參照呼叫該方法時,可以有兩種結果:
呼叫到基礎類別的方法:編譯器根據指標或參照的類型決定,稱作 early binding 呼叫到衍生類別的方法:執行時系統根據物件的實際類型決定,稱作 dynamic binding or late binding
early binding
首先使用指針建立物件
p_Amy會指向class為
Student
的物件,故output出dynamic binding or late binding
將bass class的
class Student
中的void Hello()
加上修飾字virtual
此時由於base class中的Hello()
被宣告為virtual
,此時會告訴compilierHello()
這個method會進行 dynamic binding第一種情況
derived class 有 implement此時程式執行時會連到ChemsitryStudent的Hello() output
第二種情況
derived class 沒有 implement此時程式執行時連不到ChemsitryStudent的Hello(),故會連結到Student的virtual void Hello() output
Pure Virtual Functions
知道子類別一定會衍生至此父類別,且子類別一定會有此function但表現的型態不同,故父類別不實作此function 將實作function的工作交給derived class,而且derived class一定要實作
virtual return_type function() = 0;
virtual void Hello() = 0;
output
I'm a student major in chemistry.
Abstract Classes
含有pure virtual function的class
Student
無法 實作Abstract Class的物件,必須實作其subclass多型的表現
雖然pointer皆指向 Student 這個class,但是表現出來的method不同