inheritance和recursion
假设我们有以下类:
class A { void recursive(int i) { System.out.println("A.recursive(" + i + ")"); if (i > 0) { recursive(i - 1); } } } class B extends A { void recursive(int i) { System.out.println("B.recursive(" + i + ")"); super.recursive(i + 1); } }  现在让我们在A类中调用recursive : 
 public class Demo { public static void main(String[] args) { A a = new A(); a.recursive(10); } } 
如预期的那样,产量从10下降到10。
 A.recursive(10) A.recursive(9) A.recursive(8) A.recursive(7) A.recursive(6) A.recursive(5) A.recursive(4) A.recursive(3) A.recursive(2) A.recursive(1) A.recursive(0) 
 让我们来看看令人困惑的部分。 现在我们在B类中调用recursive 
预期 :
 B.recursive(10) A.recursive(11) A.recursive(10) A.recursive(9) A.recursive(8) A.recursive(7) A.recursive(6) A.recursive(5) A.recursive(4) A.recursive(3) A.recursive(2) A.recursive(1) A.recursive(0) 
实际 :
 B.recursive(10) A.recursive(11) B.recursive(10) A.recursive(11) B.recursive(10) A.recursive(11) B.recursive(10) ..infinite loop... 
这是怎么发生的? 我知道这是一个devise的例子,但它让我感到惊讶。
较老的问题与一个具体的用例 。
 这是预料之中的。 这是B一个实例发生的事情。 
 class A { void recursive(int i) { // <-- 3. this gets called System.out.println("A.recursive(" + i + ")"); if (i > 0) { recursive(i - 1); // <-- 4. this calls the overriden "recursive" method in class B, going back to 1. } } } class B extends A { void recursive(int i) { // <-- 1. this gets called System.out.println("B.recursive(" + i + ")"); super.recursive(i + 1); // <-- 2. this calls the "recursive" method of the parent class } } 
 因此,呼叫在A和B之间交替。 
 在A的实例中不会发生这种情况,因为不会调用overriden方法。 
 因为recursive(i - 1); 在A是指this.recursive(i - 1); 这是第二种情况下的B#recursive 。 所以, super和this将被称为交替 recursion函数。 
 void recursive(int i) { System.out.println("B.recursive(" + i + ")"); super.recursive(i + 1);//Method of A will be called } 
 在A 
 void recursive(int i) { System.out.println("A.recursive(" + i + ")"); if (i > 0) { this.recursive(i - 1);// call B#recursive } } 
 其他的答案都解释了要点,一旦一个实例方法被覆盖,它将被覆盖,除非通过super否则没有得到它。  B.recursive()调用A.recursive() 。  A.recursive()然后调用recursive() ,它parsing为B的覆盖。 我们来回乒乓直到宇宙结束或StackOverflowError ,以先到者为准。 
 如果可以在A编写this.recursive(i-1)以获得自己的实现,那将是很好的,但是这可能会破坏事物并且具有其他不幸的后果,所以在A this.recursive(i-1)调用B.recursive()等等。 
 有一种方法可以获得预期的行为,但这需要先见之明。 换句话说,你必须事先知道你想在A一个子types中的super.recursive()被捕获,也就是说,在A实现中。 它是这样做的: 
 class A { void recursive(int i) { doRecursive(i); } private void doRecursive(int i) { System.out.println("A.recursive(" + i + ")"); if (i > 0) { doRecursive(i - 1); } } } class B extends A { void recursive(int i) { System.out.println("B.recursive(" + i + ")"); super.recursive(i + 1); } } 
 由于A.recursive()调用doRecursive()和doRecursive()永远不能被覆盖,所以A保证调用它自己的逻辑。 
 super.recursive(i + 1); 在B类中显式调用超类的方法,所以A recursive被调用一次。 
 然后, recursive(i - 1); 在类A中会调用类B的recursive方法,因为它是在类B一个实例上执行的,所以它将覆盖类A recursive 。 
 那么B的recursive会明确地调用A的recursive ,依此类推。 
这实际上不能走任何其他的方式。
 当你调用B.recursive(10);  ,然后打印B.recursive(10)然后用i+1调用A的这个方法的实现。 
 所以你调用A.recursive(11) ,它打印A.recursive(11) ,它调用recursive(i-1); 方法在当前实例B上input参数i-1 ,因此它调用B.recursive(10) ,然后调用超级实现与i+1是11 ,然后recursion调用当前实例recursion与i-1这是10 ,你会得到你在这里看到的循环。 
这是因为如果你调用超类中的实例的方法,你仍然会调用你调用它的实例的实现。
想象一下,
  public abstract class Animal { public Animal() { makeSound(); } public abstract void makeSound(); } public class Dog extends Animal { public Dog() { super(); //implicitly called } @Override public void makeSound() { System.out.println("BARK"); } } public class Main { public static void main(String[] args) { Dog dog = new Dog(); } } 
 你会得到“BARK”而不是一个编译错误,比如“在这个实例上不能调用抽象方法”,或者是一个运行时错误AbstractMethodError ,甚至是pure virtual method call或者类似的东西。 所以这都是为了支持多态 。 
 当B实例的recursive方法调用super类实现时,正在执行的实例仍然是B 因此,当超类的实现没有进一步的限定调用recursive , 这就是子类的实现 。 结果是你看到的永无止境的循环。