为什么在JAVA中重写的工作方式与C++有些不同
Why is overriding in JAVA working somewhat differently that from C++?
我有一些C++背景,也懂一些Java(显然远远不够)。
当我在Java或C++中看到重写行为时,它似乎没有太大区别。给出以下JAVA示例:
class Animal{
public void move(){
System.out.println("Animals can move");
}
}
class Dog extends Animal{
public void move(){
System.out.println("Dogs can walk and run");
}
}
public class TestDog{
public static void main(String args[]){
Animal a = new Animal(); // Animal reference and object
Animal b = new Dog(); // Animal reference but Dog object
a.move();// runs the method in Animal class
b.move();//Runs the method in Dog class
}
}
在Java中,使用基类引用,在C++中使用基类指针,并根据它指向的实例类型(基类对象实例或子类实例),可以实现多态性。
以上是基于您使用基类引用或指针调用实例方法,对吧?
现在我在Java中看到了这个例子。
这个Java代码中构造函数的顺序是什么?
基本上,它说如果基类函数被覆盖,那么在创建子类对象的过程中,甚至基类初始化部分也会受到影响。请参阅我从上面链接复制的以下解释:
new Son()
=>
Son._init
=> first every constructor calls super()
Father._init
Object._init
who() => is overridden, so prints "son" !!!!!
tell(name) => name is private, so cannot be overridden => "father"
who() => "son"
tell(name) => "son"
为什么会发生这种情况?我的意思是,这符合多态性应该如何使用吗?当进行初始化的基类部分时,为什么要使用子类的重写函数?
在Java文档中http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.5,我只找到这个:
与C++不同的是,Java编程语言在创建新类实例时不会为方法调度指定更改的规则。如果调用的方法在初始化对象的子类中被重写,那么即使在新对象完全初始化之前,也会使用这些重写方法
但我不知道背后的原因,感觉很奇怪。
有什么想法吗?
这是一种极为罕见的情况,C++比Java更能保护您免受枪击。(或者至少它有这样做的高尚意图。)
如果你试图从B的构造函数中调用基类B的可重写(虚拟)方法M,你很可能会在任何语言中自食其果。这是因为M很可能在派生类D中被重写,但在构建B的时候,D还没有被构建。因此,在调用D的构造函数之前调用了D.M。这可能意味着灾难。
所以,Java只是允许这种情况发生,使用风险自负。(如果你启用了足够的警告,你的编译器会告诉你你的生活很危险。)
C++也没有禁止这一点,但它稍微改变了自己的行为,以包含损坏,可以说:当你从构造函数中调用虚拟方法时,它并没有真正将其作为虚拟方法调用(通过VMT查找),而是直接将其作为非虚拟方法调用。
(要么是这样,要么是在B的构造函数中,它只是使用类B的VMT而不是D的VMT。现在想想,这是有道理的。但我不确定,自从我上次解决C++的这种行为以来,已经有很长时间了。)
- 如何在c++中为模板函数实例创建快捷方式
- 在c代码之间共享数据的最佳方式
- 在C++中将函数压缩为两种方式
- 以螺旋方式打印矩阵的程序.(工作不好)
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- 创建引用向量的优雅方式
- Constexpr替代了新的放置方式,可以让内存中的对象保持未初始化状态
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 不同/较旧的处理器运行c++代码的方式是否不同
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- 如果条件为TRUE(最佳方式?),则在do while循环中后置增量
- 重载方法的方式会在使用临时调用时生成编译器错误
- 在reactor中存储eventHandlers的最佳方式是什么
- 如何以优化的方式同时迭代两个间距不相等的数组
- 以线程安全的方式调用"QQuickPaintedItem::updateImage(const QImage&image)"(no QThread)
- 为什么C++有不同的变量初始化方式?
- 在AVX通道中混洗的最佳方式
- 如何重新定义MPI_FLOAT,MPI_DOUBLE以 typedef 的方式
- 如何以静态代码分析友好的方式使用 #define 防护?
- 以迭代方式合并标准::unordered_map