当前位置:  开发笔记 > 编程语言 > 正文

为什么JAVA中的覆盖与C++有些不同?

如何解决《为什么JAVA中的覆盖与C++有些不同?》经验,为你挑选了1个好方法。

我有一些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 doc http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.5中,我只发现了这个:

"与C++不同,Java编程语言在创建新类实例期间没有为方法分派指定更改的规则.如果调用的方法在被初始化的对象的子类中被覆盖,则使用这些覆盖方法,甚至在新对象已完全初始化."

但我不知道背后的原因,感觉很奇怪.

有什么想法吗?



1> Mike Nakis..:

这是极少数情况下,C++试图保护你不要像Java那样用脚射击自己.(或者至少它有这样做的崇高意图.)

如果你尝试从B的构造函数中调用基类B的可覆盖(虚拟)方法M,那么你很有可能用任何语言开始自己.这是因为M很可能在派生类D中被覆盖,但是在B正在建造的那一刻,D尚未建成.因此,在调用D的构造函数之前调用DM.这可能会造成灾难.

因此,Java只允许这种情况发生,使用风险自负.(如果启用了足够的警告,编译器会告诉您危险的生活.)

C++也没有禁止这一点,但它稍微改变了它的行为以便包含损坏,可以这么说:当你从构造函数中调用虚方法时,它并不真正将它作为虚方法调用(使用VMT)查找,但它直接调用它,作为非虚方法.

(无论是那个,还是从B的构造函数中,它只是使用B类的VMT而不是D的VMT.现在来想想它是有道理的.但是我不确定,我已经很久了最后麻烦这个C++的行为.)

推荐阅读
mobiledu2402851323
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有