铸造到正确的子类

时间:2010-12-25 13:22:17

标签: java

我有一个名为Car的超类,有3个子类。

class Ford extends Car{

}

class Chevrolet extends Car{

}


class Audi extends Car{

}

现在我有一个名为printMessge(Car car)的函数,它将打印特定汽车类型的消息。在实现中,我使用if语句来测试类的实例。

public int printMessge(Car car){
     if((Ford)car instanceof Ford){
            // print ford

     }else if((Chevrolet)car instanceof Chevrolet){
            // print chevrolet

     }else if((Audi)car instanceof Audi){
            // print Audi
     }
}

例如,如果我第一次使用福特printMessge(new Ford())调用它,它会打印福特消息但是当我用printMessge(new Chevrolet())调用它时,我从<{1}}获得 EXCEPTION 首先,如果声明雪佛兰不能投给福特。

我做错了什么,最好的方法是什么。

感谢

3 个答案:

答案 0 :(得分:7)

您不应该在之前使用instanceof投射instanceof的重点是动态测试它:

if (car instanceof Ford) {
    // You can safely cast to Ford *within* this block
}

...

但是,如果您控制这些类,通常最好在printMessage中使Car成为抽象方法,这样每个子类都可以自己适当地实现它。通过虚拟方法的多态性通常优于使用instanceof的显式类型测试。

答案 1 :(得分:0)

您的代码应该是这样的,以修复运行时错误:

public int printMessage(Car car) {
     if (car instanceof Ford) {
            Ford ford = (Ford) car;  // if required
            // print ford

     } else if (car instanceof Chevrolet) {
            Chevrolet chevy = (Chevrolet) car;  // if required
            // print chevrolet

     } else if (car instanceof Audi) {
            Audi audi = (Audi) car;  // if required
            // print Audi
     }
}

instanceof的想法是测试car对象的类型,以便您可以输入强制转换而不会有ClassCastException的风险。但是在测试类型之前,你的代码正在进行类转换。

话虽如此,如果printMessage方法应打印car对象的详细信息,您应该考虑将其作为Car的抽象方法,然后在每个方法中实现它具体的Car子类。当您致电car.printMessage()时,它会调度到实际汽车的printMessage()方法......而不进行任何明确的测试和类型转换。这就是@Jon Skeet的多态性意味着什么。

总是正确(甚至可能)使用多态。例如,如果printMessage()在概念上不属于Car类,或者如果Car API无法更改。对于这种情况,您可以明确地使用instanceof或通过隐藏它的各种设计模式。)

答案 2 :(得分:0)

我认为printMessage应该是Car类的一种方法。

汽车{

  public void print() {
  //do something.
  }

}

如果需要,您可以在子类中覆盖此函数。

奥迪延伸汽车{

  @Override
  public void print() {
  //do something.
  }

}

Car car1 = new Audi();
Car car2 = new Chevrolet();
car1.print();
car2.print(); .....