当前位置: 首页 > 知识库问答 >
问题:

重用继承在Java中定义方法

茅星雨
2023-03-14

我是一名新的Java开发人员,在Java中继承的概念定义我的类时遇到了一些困难。。。

在一方面,我有一个通用的类,名为车辆,它定义了几十年的属性(带有它们的getter/setters)。我有一个扩展车辆类的车辆1类。

另一方面,我有一个名为VehicleFactory的泛型类,它定义了一个静态方法,如下所示:

public class VehicleFactory {

    protected static Vehicle makeResult() {
        Vehicle result = new Vehicle();

        result.setCode("1");
        result.setNumber("2");
        // other setters methods
        return result;
    }

问题是我想创建一个Vehicle1Factory类,它有自己的makeResult方法,使用其父类的makeResult方法。但我没有做到这一点(这里的目标是优化,因为Vehicle1具有Vehicle classe的所有通用属性,但还有一些附加属性)。

我试图写的是这样的:

public class Vehicle1Factory extends VehicleFactory {

    protected static Vehicle1 makeResult() {
        Vehicle1 result = new Vehicle1();

         result = (Vehicle1) VehicleFactory.makeResult();

        // I want to reuse the makeResult of its parent class to define
        // its own makeResult method
    }
}

但是当我这么做的时候,Java告诉我有一个ClassCastException,我不能在这里使用cast。。。

在这种情况下有什么解决办法吗?

共有3个答案

韩喜
2023-03-14

因为ClassCastExctive问题已经得到了回答。我想就如何设置抽象给出一些评论。

1) 在抽象类中定义抽象工厂概念通常是个好主意。

2)我看不出“保护”和“静态”在一起有什么意义。除非你的类只被同一个包中的子类和类使用。

3) 扩展具体类并仅仅使用其静态方法是没有意义的。将静态和继承混合在一起通常是一种糟糕的做法。

无论如何,这里是带有更清晰抽象定义的示例代码:

 public class Vehicle {
    private int code = 0;
    private int number = 0;

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }
}

public class Vehicle1 extends Vehicle {
    private String engine = null;

    public String getEngine() {
        return engine;
    }

    public void setEngine(String engine) {
        this.engine = engine;
    }
}

public abstract class AbstractVehicleFactory<T extends Vehicle> {

    protected T makeVehicle() {
        T result = create();

        result.setCode(11);
        result.setNumber(24);

        return result;
    }

    protected abstract T create();
}

public class VehicleFactory extends AbstractVehicleFactory<Vehicle> {

    public static Vehicle makeResult(){
        return new VehicleFactory().makeVehicle();
    }

    @Override
    protected Vehicle makeVehicle() {
        Vehicle result = super.makeVehicle();
        return result;
    }

    @Override
    protected Vehicle create(){
        return new Vehicle();
    }
}

public class Vehicle1Factory extends AbstractVehicleFactory<Vehicle1> {

    public static Vehicle1 makeResult(){
        return new Vehicle1Factory().makeVehicle();
    }

    @Override
    protected Vehicle1 makeVehicle() {
        Vehicle1 result = super.makeVehicle();

        result.setEngine("V8");

        return result;
    }

    @Override
    protected Vehicle1 create(){
        return new Vehicle1();
    }
}
扶隐水
2023-03-14

ClassCastException发生是因为您试图将Vehicle强制转换为Vehicle1

你为什么不能这么做?因为如果对象类型为Vehicle参考类型下的Vehicle 1,您可以在case中强制转换它。

public class Vehicle1Factory extends VehicleFactory {

    protected static Vehicle1 makeResult() {
        // Change reference type to Vehicle 
        Vehicle result = VehicleFactory.makeResult();

        // I want to reuse the makeResult of its parent class to define
        // its own makeResult method
    }
}

让我们试着澄清铸造的所有黑暗点。

Super sub1 = new Sub(); // No casting required!
Super super1 = new Super();
Sub sub2 = new Sub();
sub2 = (Sub) sub1; // Casting required, because reference type is Super, but it's okay because real object under the reference is Sub();
sub2 = (Sub) super1(); // ClassCastException because real object is of Super type

最后一行的强制转换告诉编译器不要担心,我是一个好程序员,我知道我在做什么,超级类引用引用的对象在运行时实际上是Sub类的。所以没有编译时错误。但是在运行时,这失败了,因为实际对象不是Sub,而是Super

爱亮
2023-03-14

一旦创建了某事的实例,它就永远不能成为其他事物的实例。由于车辆actory.make结果创建了车辆实例,因此无法将其转换为车辆1。您必须为此创建一个新车辆1

解决方案可以是将要重用的代码移动到实用方法,例如:

class Vehicle { }

class Bike extends Vehicle { }

class VehicleFactory {
    static Vehicle create() {
        Vehicle vehicle = new Vehicle();
        initialize(vehicle);
        return vehicle;
    }

    private static void initialize(Vehicle vehicle) {
        result.setCode("1");
        result.setNumber("2");
        // ...
    }
}

class BikeFactory {
    static Bike create() {
        Bike bike = new Bike();
        VehicleFactory.initialize(bike);
        return bike;
    }
}
 类似资料:
  • 本文向大家介绍ABAP 继承-定义,包括了ABAP 继承-定义的使用技巧和注意事项,需要的朋友参考一下 示例 信息 继承使您可以从现有类派生新类。您可以使用的INHERITING FROM加法 从超类继承的CLASS子类DEFINITION 继承 。 声明。新的类子类继承了现有类超类的所有组件。新类称为派生类的子类。原始类称为新类的超类。一个类可以有多个直接子类,但可能只有一个直接超类。 类的实现

  • 问题内容: 为了完全理解如何解决Java的多重继承问题,我有一个经典的问题需要澄清。 可以说我有类此有子类和我需要做一个类,从扩展和自既是一只鸟和一匹马。 我认为这是经典的钻石问题。从我能理解经典的方式来解决,这是使,和类接口,并实现从他们。 我想知道是否还有另一种方法可以解决仍然可以为鸟和马创建对象的问题。如果有一种能够创造动物的方法,那也很棒,但不是必须的。 问题答案: 你可以为动物类(生物学

  • 假设我有类,它有子类和,我需要创建一个类,它扩展自和,因为既是鸟也是马。 我想这就是经典的钻石问题。据我所知,解决这个问题的经典方法是将、和类作为接口,并从它们实现。 我想知道是否有另一种方法来解决这个问题,在这个方法中,我仍然可以为鸟和马创建对象。如果有一种方法也能创造动物,那将是伟大的,但不是必要的。

  • 问题内容: 这是我遇到的一个测试练习问题,希望您能帮助我理解概念 让Hawk成为Bird的子类。假设某个类有两个重载的方法void foo(Hawk h)和void foo(Bird b)。在声明Bird x = new Hawk()之后,将在调用foo(x)中执行哪个版本; 这是我到目前为止的代码,有人可以向我解释为什么foo(bird b)被执行吗? 问题答案: Java执行重载解析以选择方法

  • 如何/可以重写来自非继承类的方法?其次,有没有比“非继承类”更好的术语? 我有一个“扩展”JFrame的类,需要从JPanel重写paintComponent。怎么做?或者它可以扩展JPanel,并需要访问方法,如setTitle()、setResizable()和setDefaultCloseOperation();

  • 我在一个有这些类的项目中工作: 这些coures类具有其他方法和属性。 如果可以的话,它应该能够使用来自Square和RedRectangle的方法,否则它应该使用来自Rectangle的方法,并且它应该迫使开发人员从他自己的代码中为所有在Square和RedRectangle中被重写的方法编写代码。 我实际上知道这是多重继承,Java不支持它,但我需要实现这种行为。 我试图使用Square和Re