java 和C++ 多态机制区别

本文详细解析Java和C++在多态实现上的差异,并重点介绍了虚函数的概念及其在多态中的作用。通过示例代码演示了如何在C++中声明虚函数,以及虚函数如何使得基类指针指向子类对象时能够调用正确的子类方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值