现在的位置: 首页 > 综合 > 正文

java 和C++ 多态机制区别

2013年11月23日 ⁄ 综合 ⁄ 共 2799字 ⁄ 字号 评论关闭

所以看两段小程序:
1.  Java 程序:

package com;
class Student{
	int num;
	String name;
	double score;
	Student(int num,String name,double score){
		this.name=name;
		this.num=num;
		this.score=score;
	}
	void display(){
		System.out.println("Student.display:  "+this);
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", num=" + num + ", score=" + score
				+ "]";
	}
}
class Graduate extends Student{
	double pay;
	Graduate(int num,String name,double score,double pay){
		super(num,name,score);
		this.pay=pay;
	}
	void display(){
		System.out.println("Graduate.display:  "+this);
	}
	@Override
	public String toString() {
		return "Graduate [pay=" + pay + ", name=" + name + ", num="
				+ num + ", score=" + score + "]";
	}
}
public class TA {//总结C++ 和java 在多态实现上区别。
	public static void main(String []args){
		Student stu=new Student(1001,"LI",98.5);
		stu.display();
		stu=new Graduate(1002,"Wang",87.9,79.9);
		stu.display();
	}
}

运行结果为:

Student.display:  Student [name=LI, num=1001, score=98.5]
Graduate.display:  Graduate [pay=79.9, name=Wang, num=1002, score=87.9]//执行Student类的display()代码。

2.   C++ 程序:

#include <iostream>
#include <string>
using namespace std;  
class Student
{
public:
	Student(int num,string name,float score){
		this->num=num;
		this->name=name;
		this->score=score;
	}
	void dispaly(){
		cout<<"num:"<<num<<"\nname:"<<name<<"\nscore:"<<score<<endl;
	}
protected:
	int num;
	string name;
	float score;
};
class Graduate:public Student{
private:
	float pay;
public:
	Graduate(int num,string name,float score,float pay):Student(num,name,score),pay(pay){}
	void dispaly(){
			cout<<"num:"<<num<<"\nname:"<<name<<"\nscore:"<<score<<"\npay:"<<pay<<endl;
	}
};
int main(int argc, char* argv[])    
{
	Student stu1(1001,"Li",98.5);
	Graduate grad1(1002,"Wang",87.9,79.9);
	Student *pt=&stu1;
	pt->dispaly();
	cout<<">>>>>>>>>>>>>>>>>>>>>>>>>>>>>"<<endl;
	pt=&grad1;
	pt->dispaly();//从输出结果来看,pt->display还是调用Student 类里的display 函数(没有输出pay)。
	return 0;    
} 

运行结果为:

num:1001
nameLi
score98.5
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
num:1002
nameWang
score87.9
Press any key to continue

从这两段代码比较java 和c++多态有几点不同:
1.java 里用基类引用指向子类,自动会调用子类方法。
2.C++ 里用基类指针指向子类,函数还是调用基类函数代码快,尽管数据是子类对象数据。pt=&grad1; pt->display();没有输出pay。
3.C++ 如果要实现多态的话要声明为虚函数。
    如果我们在display 前加一个virtual 关键字

	virtual void dispaly(){
		cout<<"num:"<<num<<"\nname:"<<name<<"\nscore:"<<score<<endl;
	}

运行结果就会截然不同。
运行结果为:

num:1001
name:Li
score:98.5
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
num:1002
name:Wang
score:87.9
pay:79.9
Press any key to continue

4.没有声明为虚函数由于是Student  pt 类指针,所以指针指向Student 类函数代码区。 而声明为虚函数后在对象块有一个虚函数表记录着,子类dispaly 函数。这样就执行了子类的display 函数。可以参考博客:http://blog.csdn.net/clam_clam/article/details/6919645 。
至于动态绑定机制可以参考博客:http://blog.csdn.net/clam_clam/article/details/6831975。
对于虚函数有几点需要注意:
1.虚函数只需在基类声明即可,在类外不必在家virtual 。
2.同样基类某一函数声明为虚函数(包括纯虚函数)后子类同名函数自动成为虚函数(派生类虚函数可以加virtual 也可以不加,一般为了程序清晰加上virtual 关键字)。
3.构造函数不能声明为虚函数。因为在执行构造函数时类对象还未完成建立过程,谈不上函数与类对象的关联。
4.析构函数最好声明为虚函数。这样无论指针指向类族中哪一个对象,当对象撤销时,系统会采用动态关联调用相应的析构函数,对该对象进行清理。
5.虚函数是可以调用的注意与纯虚函数区分开来。纯虚函数只是为派生类保留一个名字,纯虚函数不能被调用,同样包含纯虚函数的抽象类无法建立对象。
6.抽象类作为一个类族共同基类,为一个类族提供公共接口。抽象类虽然不能实例化但可以定义抽象类指针,通过该指针指向派生类调用相应虚函数实现多态性操作。

抱歉!评论已关闭.