Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么JAVA中的重写与C++;? 我有一些C++背景,也知道一些java(显然远远不够)。p> 当我看到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 } } 爪哇中,使用基类引用,在C++中使用基类指针,并根据它指向的实例类型(基类对象实例或子类实例),可以实现多态性。_Java_C++ - Fatal编程技术网

为什么JAVA中的重写与C++;? 我有一些C++背景,也知道一些java(显然远远不够)。p> 当我看到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 } } 爪哇中,使用基类引用,在C++中使用基类指针,并根据它指向的实例类型(基类对象实例或子类实例),可以实现多态性。

为什么JAVA中的重写与C++;? 我有一些C++背景,也知道一些java(显然远远不够)。p> 当我看到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 } } 爪哇中,使用基类引用,在C++中使用基类指针,并根据它指向的实例类型(基类对象实例或子类实例),可以实现多态性。,java,c++,Java,C++,以上是基于您使用基类引用或指针调用实例方法,对吗 现在我在Java中看到了这个例子 基本上它说如果基类函数被重写,那么在创建子类对象的过程中,甚至基类初始化部分也会受到影响。请参阅我从上述链接复制的以下说明: new Son() => Son._init => first every constructor calls super() Father._init Object._init who() => is

以上是基于您使用基类引用或指针调用实例方法,对吗

现在我在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文档中,我只找到以下内容:

“与C++不同,java编程语言在创建新类实例时没有指定用于方法调度的更改规则。如果调用的方法在初始化对象中的子类中被重写,那么在新对象完全初始化之前,使用这些重写方法。”

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


有什么想法吗 如果您试图从B的构造函数中调用基类B的可重写(虚拟)方法M,则很可能会在任何语言中攻击自己。这是因为M很可能在派生类D中被重写,但在构造B的那一刻,D还没有被构造。因此,在调用D的构造函数之前调用D.M。这可能意味着灾难

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

C++也没有禁止这一点,但它稍微改变了它的行为以控制损害,也就是说:当您从构造函数中调用一个虚拟方法时,它实际上并没有将其作为虚拟方法(使用VMT查找)调用,而是直接将其作为非虚拟方法调用


(或者,或者从B的构造函数中,它只使用B类的VMT,而不是D的VMT。现在,开始考虑它是有意义的。但是我不确定,自从我上次排除C++的行为以来,已经有很长的时间了。)< java > C++ C++是两种非常不同的语言,语义不同,java比C++小15年,在虚拟机上运行。一些比较:对于继承,你需要使用<代码>保护< /代码>。如果你想重写,请参阅参考文献:该引用是典型的java炒作。是的,最派生类中的函数总是被调用,这就是“不指定更改的规则”所指的。它忽略的是Java确实改变了规则,在本例中是初始化规则。在派生类中,所有字段都初始化为0;在大多数派生类的构造函数运行之前,它们不会获得实际的初始化值。因此,重写函数必须对零初始化和您编写的初始化都正确工作。很好的解释。谢谢。正式规则是进行虚拟调用,但对象的类型是其构造函数当前正在运行的类型。这与非虚拟通话有着微妙的区别。如果您的类层次结构为

Base
Intermediate
MostDerived
,并且
Intermediate
的构造函数调用调用虚拟函数的
Base
成员函数,您将得到该函数的
Intermediate
版本。非虚拟呼叫将获得
Base
。这并不常见,但有时确实会发生。@PeteBecker谢谢你的澄清。那么,你会说我在答案末尾的括号里写的是正确的吗?@MikeNakis-基本上,尽管它是关于实现技术而不是需求的。很多人都是这样想的。