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中具有空值的属性不足以满足我的需要。
答案 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');");