0

在讲座中,我们看到了这段代码,并告诉我们它创建了双重调度,但为什么它没有创建一个无限循环?

如果 c3po.greet(c4po); 从 TranslationRobot 调用 TranslationRobot 方法

为什么 c5po.greet(c4po); 调用 CarrierRobot 中的 AbstractRobot 方法而不是 TranslationRobot 方法,然后不调用 TranslationRobot 中的 AbstractRobot 方法,然后调用 CarrierRobot 中的 Abstract 方法等等?

是什么决定了它是否调用 AbstractRobot 方法?

抽象机器人.java

abstract class AbstractRobot extends Robot { 
abstract void greet(AbstractRobot other);
abstract void greet(TranslationRobot other);
abstract void greet(CarrierRobot other);
}

CarrierRobot.Java

class CarrierRobot extends AbstractRobot {
...
void greet(TranslationRobot other) {
    talk("'Hello from a TranslationRobot to a CarrierRobot.'"); }
void greet(CarrierRobot other) {
    talk("'Hello from a CarrierRobot to another.'"); }
void greet(AbstractRobot other) {
    other.greet(this); 
}}

翻译机器人.Java

public class TranslationRobot extends AbstractRobot {
...
void greet(TranslationRobot other) {
    talk("'Hello from a TranslationRobot to another.'"); }
void greet(CarrierRobot other) {
    talk("'Hello from a CarrierRobot to a TranslationRobot.'"); }
void greet(AbstractRobot other) {
    other.greet(this);
} } 

调度世界.Java

class DispatchWorld {
public static void main (String[] args) {
AbstractRobot c3po = new TranslationRobot();
AbstractRobot c4po = new TranslationRobot();
AbstractRobot c5po = new CarrierRobot();
AbstractRobot c6po = new CarrierRobot();
c3po.greet(c4po);
c5po.greet(c4po);
c4po.greet(c5po);
c5po.greet(c6po);
} }

这将产生输出:

Standard Model says 'Hello from a TranslationRobot to another.'
Standard Model says 'Hello from a CarrierRobot to a TranslationRobot.'
Standard Model says 'Hello from a TranslationRobot to a CarrierRobot.'
Standard Model says 'Hello from a CarrierRobot to another.'
4

1 回答 1

0

我认为,如果我们通过删除所有方法重载并改用显式不同的名称来稍微重构代码,那么为什么可以更好地说明为什么会这样以及为什么没有无限递归的答案可能会更好:

abstract class Robot
{
    void talk(String msg)
    {
        System.out.println(msg);
    }
}

abstract class AbstractRobot extends Robot
{
    abstract void greet(AbstractRobot other);

    abstract void greetFromTranslationRobot(TranslationRobot other);

    abstract void greetFromCarrierRobot(CarrierRobot other);
}

class CarrierRobot extends AbstractRobot
{
    void greetFromTranslationRobot(TranslationRobot other)
    {
        talk("'Hello from a TranslationRobot to a CarrierRobot.'");
    }

    void greetFromCarrierRobot(CarrierRobot other)
    {
        talk("'Hello from a CarrierRobot to another.'");
    }

    void greet(AbstractRobot other)
    {
        other.greetFromCarrierRobot(this);
    }
}


public class TranslationRobot extends AbstractRobot
{
    void greetFromTranslationRobot(TranslationRobot other)
    {
        talk("'Hello from a TranslationRobot to another.'");
    }

    void greetFromCarrierRobot(CarrierRobot other)
    {
        talk("'Hello from a CarrierRobot to a TranslationRobot.'");
    }

    void greet(AbstractRobot other)
    {
        other.greetFromTranslationRobot(this);
    }
}

从编译器的角度来看void greet(AbstractRobot other), methodsvoid greet(TranslationRobot other)void greet(CarrierRobot other)3 种明显不同的方法,我的重命名只是强调了这些方法。

因此,类似的调用c3po.greet(c4po)实际上是将TranslationRobot.greet其转发给other.greetFromTranslationRobot(this)哪个调用,TranslationRobot.greetFromTranslationRobot并且显然不应该导致任何无限递归。

于 2017-03-14T20:20:20.117 回答