Java - 是否可以使用单个类扩展类的所有子类?

时间:2016-02-20 12:21:30

标签: java inheritance

Java - 是否可以使用单个类扩展类的所有子类?

让我们用一个例子解释一下,实际的代码要复杂得多。我有一个Animal类,它有自己的类层次结构。假设它有两个子类:Testarrosa和Viper。

public class Car {

    public abstract String getManufacturer();
}

public class Testarossa extends Car{

    public String getManufacturer(){
        return "Ferrari";
    }
}

public class Viper extends Car{

    public String getManufacturer(){
        return "Dodge";
    }
}

我想用RegisteredCar子类扩展所有Car子类。

public class RegisteredCar extends Car {

   private String plateNumber;

   public RegisteredCar (String plateNumber){
       this.plateNumber=plateNumber;
   }

   public String getPlateNumber() {
       return plateNumber;
   }
}

在某些时候,我应该能够创建一个特定子类的新RegisteredCar。像

这样的东西
RegisteredCar c = new RegisteredCar<Viper>("B-3956-AC");

并调用c.getManufacturer()获取“Dodge”和c.getPlateNumber()以获得B-3956-AC。显然,我仍然可以创建Car c = new Viper();

这是一个例子。如果没有注册,在Car中具有空值的属性不足以满足我的需要。

8 个答案:

答案 0 :(得分:10)

简而言之,这是不可能的。不幸的是,您必须修改对象模型。

例如,如何以这种方式获得Registration课程:

public interface Registration<C extends Car> {
    C getCar();

    String getPlateNumber();
}

通过这种方式,您可以在保留Car模型的同时,在单个班级中提取与注册相关的信息。

然后你可以做辅助方法,如:

Registration<Viper> registeredViper = createRegistration(new Viper(), "B-3956-AC");

答案 1 :(得分:4)

正如其他人所说的那样,没有那些不太可能,你的例子可以通过改变你的模型来解决

作为继承的替代方法,您可以使用另一个类来包装Car实例 我会使Car成为一个接口(虽然RegisteredCar扩展Car也应该工作),然后尝试类似下面的伪代码:

class RegisteredCar<T extends Car> implements Car {
   private final  T car

   RegisteredCar(T car) {
     this.car = car;
   }

   ... methods for RegisteredCar
   ... methods from Car delegating to `this.car`
}

请原谅有些不好的代码,我没有打开IDE,而且我总是在没有IDE的情况下弄乱泛型。

另一个可能的解决方案是使用AOP,虽然我不知道现在如何流行,但你所描述的可能是一个跨领域的问题。

最后一种选择可能是使用一种语言,允许扩展,特征,协议或其他类型的混合&#39;

答案 2 :(得分:2)

在java中,禁止扩展超过1个类。 例如,您可以从类构建链以扩展。 为解决Java中的多重继承问题→使用了接口

答案 3 :(得分:2)

你应该尽可能地避免继承。使用抽象(接口)使您的代码更优雅,可维护。只是谷歌为什么延伸是邪恶的

    public interface Car{
        String getManufacturer();
    }

    public interface Registerable{
        boolean isRegistered();
        void    register(String plateNumber);
        void    getPlateNumber();
    }

    public class Viper implements Car, Registerable
    {
      //all methods
    }

答案 4 :(得分:1)

不,它不像C ++。 Java中不可能有多重继承。但是,您可以实现多个接口。

答案 5 :(得分:1)

使用其他答案中描述的Generic类方法,您将无法使用RegisteredCar来传递Car对象。例如假设您需要生成一些发票。

Invoice getInvoice(Car c);

在此方法中,您不能使用RegisteredCar,因为它不是类型Car。所有需要Car的API都不适用于RegisteredCar。在某些情况下,您可能需要Plate Number以及Car,在那里您可能需要保留Plate Number和Cars的映射。我建议遵循基于Decorate Pattern的方法,并将所有Car调用委托给传递的car对象

    public class RegisteredCar extends Car{

    public RegisteredCar(Car c, String plateNumber){

    }        
    @Override
    String getColor(){
       c.getColor();
    }
}

答案 6 :(得分:0)

你无法通过继承实现这一目标。 您最好的选择是使RegisteredCar类型具有通用性,然后使用包含预期类型汽车的通用实例变量:

public class RegisteredCar<T extends Car> {
   private String plateNumber;
   private T car;

   public T getCar() {
       return this.car;
   }
   public T setCar(T car) {
       this.car = car;
   }
   public RegisteredCar (String plateNumber){
       this.plateNumber=plateNumber;
   }
   public String getPlateNumber() {
       return plateNumber;
   }
}

通过这种方式,您将能够将任何类型的对象传递给RegisteredCar,这是Car的子类。

您可以注意到,我已删除此课程的extends Car部分,因为它不需要成为汽车本身的子类。

答案 7 :(得分:0)

在实际课程中,您是否有理由不能简单地将新功能添加到现有基类中?

db.execSQL("INSERT INTO POINTS_TABLE (COL1,COL2,Col3) VALUES ('NULL','NULL','NULL');");