Java 从parentclass对象调用childclass方法的最佳实践
我知道这个问题听起来令人困惑。让我澄清一下 班车。。。 奔驰级轿车。。。 类保时捷扩展车。。。 类仓库{ 汽车; } 类WarehouseX扩展了仓库{ 公共静态真空总管{ 梅赛德斯超级轿车; } } 看看这个虚构的例子。梅赛德斯和保时捷是一辆汽车。每个仓库都有一辆车。 现在,WarehouseX有一辆奔驰。然而,WarehouseX从Warehouse继承了一辆通用汽车。Java 从parentclass对象调用childclass方法的最佳实践,java,oop,inheritance,casting,Java,Oop,Inheritance,Casting,我知道这个问题听起来令人困惑。让我澄清一下 班车。。。 奔驰级轿车。。。 类保时捷扩展车。。。 类仓库{ 汽车; } 类WarehouseX扩展了仓库{ 公共静态真空总管{ 梅赛德斯超级轿车; } } 看看这个虚构的例子。梅赛德斯和保时捷是一辆汽车。每个仓库都有一辆车。 现在,WarehouseX有一辆奔驰。然而,WarehouseX从Warehouse继承了一辆通用汽车。 在这辆车上调用特定梅赛德斯方法的最佳方式是什么。一种方法是把它扔给奔驰,但我觉得这很难看。有更好的方法来实现这一点吗?您不
在这辆车上调用特定梅赛德斯方法的最佳方式是什么。一种方法是把它扔给奔驰,但我觉得这很难看。有更好的方法来实现这一点吗?您不应该在这个方向上创建依赖项,超类无法知道子类实现了什么 一种解决方案是在超类中创建一个抽象方法
//Car class
public abstract void doModelSpecificStuff();
然后在你汽车课上的某个地方叫它。然后,每个子类实现这个方法,并执行特定于该车型的操作
//Mercedes class
@Override
public void doModelSpecificStuff() {
doMercedesStuff();
}
仓库代码将是
class WarehouseX extends Warehouse{
public static void main(){
Warehouse warehouse = new WarehouseX();
warehouse.car.doModelSpecificStuff();
}
}
为了跟进遗留问题的答案,如果您将仓库设置为通用的,那么您可以这样做
class WarehouseX extends Warehouse<Mercedes>{
//...
public void someMethod() {
car.doModelSpecificStuff();
}
}
由于每个仓库只应拥有一种特定的汽车类型,因此可以使用泛型:
class Warehouse<T extends Car>{
T car;
}
class WarehouseX extends Warehouse<Mercedes>{
//do mercedes stuff
}
WarehouseX现在可以访问super.car并将其用作Mercedes,因为继承
保证它
编辑:既然人们在谈论抽象方法:Car应该实现通用方法并声明抽象方法,如果每个特定的Car需要提供它们的话。如果只有特定car的一个子集需要一个方法,比如openBackDoors,那么应该声明一个新的类扩展car。这样做违反了依赖倒置原则。有关详细信息,请参阅实体原则。 Joakim解释了最佳实践。 但你可以试试这个: 而不是:
Warehouse warehouse = new WarehouseX();
warehouse.car.doModelSpecificStuff();
try this:
getCar().doModelSpecificStuff();
//in Warehouse class
//getters //not pivate
//setters
您可以尝试下面的代码。 我们的想法不是为每辆车创建多个仓库类别。 将代码位设为泛型,并在创建仓库对象时在仓库中使用InjectCar
abstract class Car{
public abstract void doCarStuff();
}
class Mercedes extends Car{
@Override
public void doCarStuff() {
System.out.println("Mercedes stuff");
}
}
class Ferrari extends Car{
@Override
public void doCarStuff() {
System.out.println("Ferrari stuff");
}
}
class Warehouse{
private Car car;
public Warehouse(Car car) {
this.car = car;
}
public Car getCar() {
return car;
}
}
public class TestCarWarehouse {
public static void main(String[] args) {
Warehouse warehouseX = new Warehouse(new Mercedes());
warehouseX.getCar().doCarStuff();
Warehouse warehouseY = new Warehouse(new Ferrari());
warehouseY.getCar().doCarStuff();
}
}
你可以给Car一个方法doBrandSpecificStuff,在Mercedes和Porsche中通过调用真正的方法来覆盖它,比如@override public void doBrandSpecificStuff{doMercedesStuff;}。也有点难看,但我更喜欢它而不是铸造实例。。。顺便说一句,汽车可以是一个界面,不是吗?你在找一个通用的汽车容器吗?或者你需要对仓库做什么?是的,这是可行的,但这意味着你需要一个超级方法来处理每一个方法。此外,如果说梅赛德斯有一个方法自动更正,而保时捷没有这种能力,那么我们如何证明这一点呢?混合了静态/实例的代码片段不起作用,应该更改。问题中的代码不清楚,在没有初始化的情况下从main调用一个实例,所以我选择了一条捷径,可能是简略的:由于通用WarehouseX确实知道它拥有一辆Mercedes,因此知道Mercedes方法。WarehouseX是仓库的具体化,因此不是通用的,但仍然在WarehouseX中,这辆车是梅赛德斯型的。这是因为我们这么说,T必须是一个具体的类,它从Car扩展而来,因此增加了更多information@JoakimDanielson这不是泛型的重点。当然,在使用之后,汽车实例不再是普通汽车了。是的,我的大脑放屁了。我删除我的评论。我在考虑使用像Warehouse w=new WarehouseX这样的泛型;