超类和子类参数

时间:2015-12-30 13:39:09

标签: java inheritance polymorphism overloading override

我提供两个课程如下:

设备类

public class Appliance {
    void start(Appliance t){
        System.out.println("Start Appliance");
    }
}

烤面包机类

public class Toaster extends Appliance {
    void start(Toaster t){
        System.out.println("Start Toaster");
    }
}

RunAppliance类

public class RunAppliance {
    public static void main(String[] args) {
        Appliance appliance = new Toaster();
        Toaster toaster = new Toaster();
        appliance.start(toaster);
    }
}

作为一个新手,它让我在方法重载和覆盖之间混淆,以及参数如何在一个参数类型中受影响是另一个参数类型的子类。因此,我提出了相同的6个条件:

1)设备类:void start(设备 t); Toaster Class :void start( Appliance t)

2)设备类:void start( Toaster t); Toaster Class :void start( Toaster t)

3)设备类:void start(设备 t); Toaster Class :void start( Toaster t)

4)设备类:void start( Toaster t); Toaster Class :void start( Appliance t))

5)设备类:void start(设备 t)& void start( Toaster t); Toaster Class :void start( Toaster t)

6)设备类:void start(设备 t); Toaster Class :void start( Appliance t)& void start( Toaster t))

任何人都可以为我建议一个必要的规则。

2 个答案:

答案 0 :(得分:1)

您的Toaster课程不正确。其start()方法的参数应为Appliance,而不是Toaster

您的实施未通过Liskov替代原则。您无法使用Toaster调用Appliance的任何地方,因为它不会覆盖所写的start()方法。

这样做:

public class Toaster extends Appliance {
    void start(Appliance a){
        System.out.println("Start Toaster");
    }
}

答案 1 :(得分:0)

我认为您在询问以下每种情况的输出结果:

    Appliance appliance = new Appliance();
    Appliance applianceToaster = new Toaster();
    Toaster toaster = new Toaster();
    appliance.start(appliance);
    appliance.start(toaster);
    appliance.start(applianceToaster);
    toaster.start(appliance);
    toaster.start(toaster);
    toaster.start(applianceToaster);
    applianceToaster.start(appliance);
    applianceToaster.start(toaster);
    applianceToaster.start(applianceToaster);

正如@duffymo指出的那样,在Toaster start方法中将Toaster更改为Appliance。 Toaster中的开始将在设备中为运行时Toaster的任何对象隐藏启动。您需要使用super来从Toaster的开头访问Appliance中的开始。

在编译时,设备看起来像Appliance,在运行时它是一个设备,因此无论向哪个参数发送,都会调用Appliance中的启动。

在编译时,烤面包机看起来像Toaster,在运行时它是一个Toaster,因此无论向哪个参数发送,都会调用Toaster的开头。

在编译时,applianceToaster看起来像Appliance,在运行时它是一个Toaster,因此无论发送给它的参数如何,都会在Toaster中启动多态调用。