Different
Different
目录
继承
继承 - 类继承
继承
java (在Java中,所有的继承都是公有继承,而没有C++中的私有继承和保护继承)
public class Manager extends Employee { // ... }
C++
class A : public APerent {}
多继承(不支持)
- C++支持多继承
- Java不支持多继承
继承 - 方法继承
重载、覆盖、隐藏(override、Override、hide)
C++中的重载、覆盖、隐藏(override、Override、hide)
相同范围:重载
不同范围:覆盖或隐藏(即:继承 x 多态)
函数名 参数 基类有virtual关键字 结果 相同 不同 有或无 隐藏 相同 相同 无 隐藏 相同 相同 有 覆盖
Java中的重载、覆盖、隐藏(override、Override、hide)
不同范围
函数名 参数 Java默认使用动态绑定,否则final 结果 相同 不相 —— ?? 相同 相同 —— 覆盖
覆盖方法、选择方法版本
继承(inheritance):子类自动地继承了父类中的方法
覆盖(Override):提供一个新的方法来覆盖(Override)超类中的原方法
如果希望调用超类而不是子类的方法
Java:使用特定的关键字super解决这个问题
super.getSalary()
C++:使用
::
父类名::getSalary()
注意:有些人认为super与this引用是类似的概念,实际上,这样比较并不太恰当。这是因为super不是一个对象的引用,不能将super赋给另一个对象变量,它只是一个指示编译器调用超类方法的特殊关键字
子类构造器
C++
A::A():PerentA(){}
// 一般使用成员初始化列表语法(效率高)来调用基类构造函数
// 缺省时:
// 如果省略基类的构造函数,则程序自动使用默认的基类构造函数
Java
public Manager(String name, double salarym, int year, int month, int day)
{
super(name, salary, year, month, day);
// 使用super调用构造器的语句必须是子类构造器的【第一条】语句
// 这里的关键字super具有不同的含义
// 是“调用超类Employee中含有n、s、year、month和day参数的构造器”的简写形式
bonus = 0;
}
// 缺省时:
// 如果子类的构造器没有显式地调用超类的构造器,则将自动地调用超类默认(没有参数)的构造器
// 如果超类没有不带参数的构造器,并且在子类的构造器中又没有显式地调用超类的其他构造器,则Java编译器将报告错误。
动态绑定
一个对象变量(例如,变量e)可以指示多种实际类型的现象被称为多态(polymorphism)
在运行时能够自动地选择调用哪个方法的现象称为动态绑定(dynamic binding)
C:默认是静态绑定
Java:不需要将方法声明为虚拟方法。动态绑定是默认的处理方式。如果不希望让一个方法具有虚拟特征,可以将它标记为final
继承 - 其他
阻止继承
Java
作用1:不允许类被继承 例如,假设希望阻止人们定义Executive类的子类,就可以在定义这个类的时候,使用final修饰符声明
public final class Executive extends Manager { ... }
作用2:不允许类方法被复写 类中的特定方法也可以被声明为final。如果这样做,子类就不能覆盖这个方法(final类中的所有方法自动地成为final方法)
public class Emplyee { ... public final String getName() { return name; } ... }
C++11,final关键字
作用1:不允许类被继承
struct Basel final{}; // 不让别人继承自己 struct Derived1:Base1 {}; // 此时会报错
作用2:不允许类方法被复写
struct Base2{ virtual void f() final; // 不允许被复写 }; struct Derived2:Base2{ void f(); }
用途:将方法或类声明为final主要目的是:确保它们不会在子类中改变语义。例如在Java中:
- Calendar类中的getTime和setTime方法都声明为final 这表明Calendar类的设计者负责实现Date类与日历状态之间的转换,而不允许子类处理这些问题
- String类也是final类 这意味着不允许任何人定义String的子类。 换言之,如果有一个String的引用,它引用的一定是一个String对象,而不可能是其他类的对象。
方法/域的访问权限(保护访问)
Java
// priveate:仅对本类可见 // public:对所有类可见 // protected:对本包和所有子类可见 // 默认:对本包可见
C++
- 基本同上
总结
- Java中的受保护部分对所有子类及同一个包中的所有其他类都可见。这与C++中的保护机制稍有不同
- Java中的protected概念要比C++中的安全性差
【功能扩展】继承
【功能扩展】继承 x 转换,强制类型转换
与C++不同
类型转换 Java使用的类型转换语法来源于C语言,但处理过程却有些像C++的dynamic_cast操作。以下两种写法等价
Java
Manager boss = (Manager) staff[1]; // Java
C++
Manager* boss = dynamic_cast<Manager*>(staff[1]); // C++
判断是否能转换
Java:当类型转换失败时,抛出一个异常(有点像C++中的引用(reference)转换)
if (staff[1] instanceof Manager) // Java,需要将instanceof运算符和类型转换组合起来使用 { boss = (Manager) staff[1]; ... }
C++:当类型转换失败时,生成一个null对象
Manager* boss = dynamic_cast<Manager*>(staff[1]); // C++,直接转换 if (boss != NULL) ...