C++中子类复写父类virtual方法要做到函数参数和返回值类型都一致,而Java中返回值类型可以不同,即子类复写的方法返回值类型可以使父类方法返回值类型的一个子类型。比如
返回类型兼容情况
Java 中不同返回值类型复写
public class Demo {
public static void main(String[] args) {
X x = new Y();
System.out.println(x.getValue());
}
}
public class X {
public Number getValue() {return new Integer(0);}
}
class Y extends X {
public Double getValue() {return new Double(1.0);}
}
上述代码能够成功编译比执行输出1.0
。不过对于基本数值类型还是不行的,如下代码无法通过编译:
class X {
public int getValue() {return 0;}
}
class Y extends X {
public long getValue() {return 1;}
}
C++中要求严格一致
class Object {
};
class SpecialObject : public Object {
};
class A {
public:
virtual Object getValue() {
return Object();
}
};
class B: public A {
public:
virtual SpecialObject getValue() {
return SpecialObject();
}
};
int main() {
A* x = new B();
return 0;
}
报如下错误:
virtual.cpp:21:24: error: virtual function 'getValue' has a different return type ('SpecialObject') than the function it overrides
(which has return type 'Object')
virtual SpecialObject getValue() {
~~~~~~~~~~~~~ ^
virtual.cpp:13:17: note: overridden virtual function is here
virtual Object getValue() {
~~~~~~ ^
1 error generated.
可见性
Java
Java中要求子类复写父类方法时,其可见性不能低于父类。如下代码将报错
class X {
public int getValue() { return 0;}
}
class Y extends X {
private int getValue() { return 1;}
}
C++
对复写方法可见性不要求,如下代码可以顺利编译并运行,输出为1.
class A {
public:
virtual int getValue() {
return 0;
}
};
class B: public A {
private:
virtual int getValue() {
return 1;
}
};
int main() {
A* x = new B();
cout<<x->getValue()<<endl;
return 0;
}
异常处理
Java
Java可以在方法参数后用throws指出可能会抛出的异常,来回避try-catch块。当子类中复写这样的方法时,子类中的方法声明抛出的异常范围不能超过父类中所定义的。
如下是可以的,虽然throws声明不是完全一致,子类声明抛出的异常类型是父类声明抛出异常类型中的子类。
class X {
public void call() throws Exception {}
}
class Y extends X {
public void call() throws IOException, ClassCastException {}
}
但是下面的就不行
class X {
public void call() throws IOException {}
}
class Y extends X {
public void call() throws Exception {}
}
C++
C++中没有类似throws声明