C++和JAVA中一些区别,包括指向子类的引用会调用谁的方法,子类构造函数自动调用父类构造函数时,父构造会调用的谁方法

时间:2021-08-19 19:25:03
/*
* 不同于C++,JAVA中子类总是重写父类函数。C++中子类只重写父类的虚函数。
* 不同于C++,JAVA中指向子类对象的父型引用,依然优先调用子类对象的函数。C++相反。
* 不同于C++,JAVA中子类的构造函数自动调用父类的构造函数,若父类的构造函数中调用了方法,依然是子类优先。C++相反
*/

package test;

class father{
father(){
print("who are you?");
}
void print(String str){
System.out.println("FATHER: "+str);
}
}
class son extends father{
void print(String str){
System.out.println("SON: "+str);
}
}
public class Gouzaoextends {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
father obj = new son();
obj.print("str");
}

}


/**C++
1)基类的指针指向派生类对象:那么该指针只能够调用基类所定义的函数原型,
如果该函数为虚函数,则调用该派生类自己的成员函数。
如果不是虚函数,则调用基类的函数。
2)如果以派生类的指针指向基类对象,则必须事先做明显的转型操作,但是这种做法很危险。
*/
/**
对于const类对象/指针/引用,只能调用类的const成员函数,因此,const修饰成员函数的最重要作用就是限制对于const对象的使用。

a. const成员函数不被允许修改它所在对象的任何一个数据成员。

b. const成员函数能够访问对象的const成员,而其他成员函数不可以。

c. const成员函数也不能调用类中任何非const成员函数。

*/
#include "iostream"
using namespace std;
class A{
public:
A(){
func(0);
}
virtual void func(int data){
cout<<"A1:"<<data<<endl;
}
//下面的函数,子类中未覆盖---const对象调用
virtual void func(int data)const{
cout<<"A2:"<<data<<endl;
//func("A3");//也不能调用类中任何非const成员函数。

}
void func(char* str){
cout<<"A3 "<<str<<endl;
}
virtual void func2(int data)const{
cout<<"A4:"<<data<<endl;
}
};

class B:public A{
public:
B():A(){//A()中会调用A的方法,即使该方法是虚函数,B中也覆盖了。---不同于JAVA
func(0);
}
void func(){
cout<<"B1: "<<""<<endl;
}
//覆盖了基类的虚函数
void func(int data){
cout<<"B2:"<<data<<endl;
}
//未覆盖
void func(char* str){
cout<<"B3 "<<str<<endl;
}
//覆盖了基类的虚函数
void func2(int data)const{
cout<<"B4:"<<data<<endl;
}
};

int main(){
A *pA;
B b;//默认调用基类构造函数,基类构造函数还是调用了基类的函数!!--JAVA相反。
cout<<"B b"<<endl;
b.func("bstr");

const A *pcA;//const,很特殊

pA = &b; //子类对象交给基类指针
pA->func(1);//子类方法-覆盖基类虚函数
cout<<"pA->func(1);"<<endl;

pA->func("test");//优先调用基类的非virtual方法
cout<<"pA->func('test');"<<endl;

A().func(1);

pcA = &b;
pcA->func(2);//A2: 2

pcA->func2(3);//B4: 3

return 0;
}