Java—是否可以用一个类扩展一个类的所有子类?
Java—是否可以用一个类扩展一个类的所有子类 让我们用一个例子来解释它,实际的代码要复杂得多。我有一个动物类,它有自己的类层次结构。假设它有两个子类:Testarrosa和ViperJava—是否可以用一个类扩展一个类的所有子类?,java,inheritance,Java,Inheritance,Java—是否可以用一个类扩展一个类的所有子类 让我们用一个例子来解释它,实际的代码要复杂得多。我有一个动物类,它有自己的类层次结构。假设它有两个子类:Testarrosa和Viper public class Car { public abstract String getManufacturer(); } public class Testarossa extends Car{ public String getManufacturer(){ retur
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");
RegisteredCar c=新的RegisteredCar(“B-3956-AC”);
调用c.getManufacturer()获得“道奇”,调用c.getPlateNumber()获得B-3956-AC。显然,我仍然能够创建一辆Car c=new Viper()代码>
这就是一个例子。如果没有注册,在Car中有一个空值的属性是不够的。在java中,禁止扩展超过一个类。
例如,您可以构建从类到扩展的链。
解决Java中的多重继承问题→ 使用接口简而言之,不,这是不可能的。不幸的是,您必须修改对象模型
例如,以这种方式注册类怎么样:
公共接口注册{
C getCar();
字符串getPlateNumber();
}
通过这种方式,您可以在维护车型的同时,提取与单个类别中的注册相关的信息
然后可以执行以下帮助器方法:
Registration RegisteredPiper=createRegistration(新Viper(),“B-3956-AC”);
<> >不,它不像C++。多重继承在Java中是不可能的。但是,您可以实现多个接口。继承无法实现这一点。
最好的选择是将RegisteredCar类型设置为泛型,然后使用一个泛型实例变量来保存所需类型的car:
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;
}
}
公共类注册卡{
私有字符串编号;
私家车;
公共T getCar(){
归还这辆车;
}
公共T车(T车){
这辆车;
}
公共注册卡(字符串编号){
这个。plateNumber=plateNumber;
}
公共字符串getPlateNumber(){
返回车牌号;
}
}
有了它,您将能够向RegisteredCar传递属于Car子类的任何类型的对象
正如您所注意到的,我已经删除了这个类的扩展Car
部分,因为它不需要是Car本身的子类。您应该尽可能避免继承。使用抽象(接口)使代码优雅且可维护。只是谷歌为什么扩展是邪恶的。
正如其他人所说,不,这是不可能的,你的例子可以通过改变你的模型来解决
作为继承的替代方法,您可以使用另一个类包装Car
实例。
我会制作Car
一个接口(尽管拥有RegisteredCar
extendCar
也应该可以),然后尝试以下伪代码:
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`
}
类RegisteredCar实现Car{
私家车
登记车辆(T车){
这辆车;
}
…RegisteredCar的方法
…从Car授权到“this.Car”的方法`
}
请原谅我的代码有点糟糕,我没有打开IDE,我总是在没有IDE的情况下搞乱泛型
另一个可能的解决方案是使用AOP,尽管我不知道这是如何流行的,但您所描述的可能是一个跨领域的问题
最后一种选择可能是使用一种允许扩展、特征、协议或其他类型的“混合”的语言,如其他答案中所述,使用通用类方法,您将无法在需要传递Car
对象的地方使用RegisteredCar
。e、 假设您需要生成一些发票
Invoice getInvoice(Car c);
在此方法中,您不能使用RegisteredCar
,因为它不是Car类型。所有需要Car的API都不适用于RegisteredCar
。在某些情况下,您可能需要车牌号和汽车,在那里您可能需要保持车牌号和汽车的映射。我建议采用以下基于装饰模式的方法,并将所有Car调用委托给传递的Car对象
public class RegisteredCar extends Car{
public RegisteredCar(Car c, String plateNumber){
}
@Override
String getColor(){
c.getColor();
}
}
在实际的类中,有没有一个原因是您不能简单地将新特性添加到现有的基类中
public abstract class Car
{
public abstract String getManufacturer() ;
protected String plate_number = null ;
public String getPlateNumber()
{ return this.plate_number ; }
public boolean isRegistered()
{ return ( this.plate_number != null ) ; }
}
“假设它有两个子类:大猩猩和狼”。。我想你应该坚持你的汽车example;)。但是不,这是不可能的。不可能将Viper和Testarossa的基类更改为RegisteredCar吗?我不明白为什么布尔成员“registered”是不够的。未注册的默认行为由假值处理。我想说,以这种方式使用继承确实是一个非常糟糕的设计。我要说的是,将继承用于make同样可怕。啊!几乎和我的答案一样。我只需要让它实现Car
接口,然后它就可以在使用Car
的地方使用,只需将实现的方法委托给包装好的Car
实例即可。这不是多重继承的问题。我不想创建一个从多个类继承的类。这是一个遗传的问题;您不知道要扩展哪个类。类继承一点也不邪恶。您的解决方案迫使程序员在每个子类中实现通用方法。如果您需要公共功能,您可以实现该功能,将其抽象出来,并将该抽象组合到所有需要它的类中。通过这种方式,您将避免对实现的依赖,您将能够更改实现,并且没有人会注意到这一点,因为实现是完全隐藏的。这被称为组合重于继承。小茶
public abstract class Car
{
public abstract String getManufacturer() ;
protected String plate_number = null ;
public String getPlateNumber()
{ return this.plate_number ; }
public boolean isRegistered()
{ return ( this.plate_number != null ) ; }
}