java 和C++ 多态机制区别

来源:互联网 发布:imap4 端口设置 编辑:程序博客网 时间:2024/06/04 17:58

所以看两段小程序:
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);}@Overridepublic 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);}@Overridepublic 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:1001nameLiscore98.5>>>>>>>>>>>>>>>>>>>>>>>>>>>>>num:1002nameWangscore87.9Press 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:1001name:Liscore:98.5>>>>>>>>>>>>>>>>>>>>>>>>>>>>>num:1002name:Wangscore:87.9pay:79.9Press 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.抽象类作为一个类族共同基类,为一个类族提供公共接口。抽象类虽然不能实例化但可以定义抽象类指针,通过该指针指向派生类调用相应虚函数实现多态性操作。




原创粉丝点击