今天看了马士兵老师的JAVA视频,才发现自己对JAVA面向对象这一块了解的太不深入了.这里先说说JAVA的多态性,以及与C++多态性的区别.
JAVA多态性的三个条件:
1.必须要有继承;
2.必须要有重写;
3.基类引用指向基类或子类对象.
先看代码
public class Test {
public static void main(String[] args) {
Test t = new Test();
t.out(new base());
t.out(new child()); //基类引用指向子类对象
}
public void out(base b){ //b指向哪个对象就调用哪个对象的out函数
b.out();
}
}
class base {
public void out(){
System.out.println("base");
}
}
class child extends base { //继承
public void out(){ //重写
System.out.println("child");
}
}
|
输出: base
child
个人感觉JAVA的多态性相对容易一点,下面再看看C++的多态性:
先看代码:
#include <iostream>
using namespace std;
class base {
public:
void out() {
cout<<"base"<<endl;
}
};
class child :public base {
public:
void out() {
cout<<"child"<<endl;
}
};
void out(base b) {
b.out();
}
int main() {
base b;
out(b);
child c;
out(c);
system("pause");
return 0;
}
|
很不幸,程序的输出是: base base 也就是说程序根本没有实现动态绑定
修改一下:
#include <iostream>
using namespace std;
class base {
public:
virtual void out() { //注意这里的virtual
cout<<"base"<<endl;
}
};
class child :public base {
public:
virtual void out() { //这里virtual不写也可以
cout<<"child"<<endl;
}
};
void out(base* b) {
b->out();
}
int main() {
base *b = new base();
base *c = new child();
out(b);
out(c);
delete b;
delete c;
system("pause");
return 0;
}
|
这里的输出是 base child,也就是说实现了动态绑定
下面的程序同样也实现了动态绑定
#include <iostream>
using namespace std;
class base {
public:
virtual void out() {
cout<<"base"<<endl;
}
};
class child :public base {
public:
virtual void out() {
cout<<"child"<<endl;
}
};
void out(base &b) { //这里将指针改成了引用
b.out();
}
int main() {
base b;
child c;
out(b);
out(c);
system("pause");
return 0;
}
|
为什么会这样呢?
引自C++ Primer中的几段话:
C++中面向对象编程的一个颇具讽刺意味的地方是,不能用对象支持面向对象编程,相反,必须使用指针或引用.
在C++中,通过基类引用(或指针)调用虚函数时发生动态绑定,引用(或指针)既可以指向基类对象,也可以指向子类对象,这一事实是动态绑定的关键.引用(或指针)调用的虚函数在运行时确定,被调用的函数是引用(或指针)所指对象的实际类型所定义的.
在C++中,多态性仅用于通过继承而相关联的类型的引用或指针.
看完上面几段过应该就差不多明白了.
跟JAVA相对应,C++多态性的三个条件:
1.必须要有继承;
2.必须要有重写,而且重写的必须是虚函数;
3.基类引用(或指针)指向基类或子类对象.