假设您在Java中有一个类和一个子类:
public abstract class Car {
public static Car getCar() {
Car car = makeCar();
return car;
}
private static Car makeCar() {
//bunch of code that makes the car
return car;
}
}
public class Ferrari extends Car {
private static makeCar() {
//bunch of code that makes a Ferrari! Yeah!
awesomeRide = new Car();
return awesomeRide;
}
}
然后在另一堂课中你打电话:
Ferrari.getCar();
将调用法拉利的超级类getCar()和 makeCar()方法。法拉利不能@Override getCar()因为在Java中,静态方法无法被覆盖。
所以在Car的getCar()方法中,如何判断方法调用是否发送到法拉利类,而不是类Car?由于它是一种静态方法,我显然不能if(this instanceOf Car)
。
但我不知道的是,根据Java的文档,虽然静态方法无法在Java中覆盖,但它可以隐藏。
隐藏和覆盖之间的关键区别在于,隐藏时,静态方法在同一个类上调用其他静态方法,而不是它们从中路由的子类。
这意味着,如果这些不是静态方法,那么无论何时调用者调用myFerrariInstance.getCar(),法拉利的makeCar()总是会被Car的getCar()方法调用。然而,隐藏起来,法拉利的makeCar()将永远不会被Car的getCar()方法调用,因为makeCar()也是同一类的静态方法。
答案 0 :(得分:8)
所以在Car的getCar()方法中,如何判断方法调用是否发送到法拉利类,而不是类,Car
你不能。 (我认为javac
使用为两个调用生成相同的字节码 - 它现在没有,但我不相信有任何方法可以检测哪个电话是在执行时发出的,如果在JITting期间它仍然丢失了这些信息,我不会感到惊讶。)
如果你觉得你需要这样做,你应该改变设计 - 要么显着改变,要么只是将相关的类作为参数传递给方法。
你可以为每个子类提供一个具有相同签名的静态方法。这不会是最重要的,但它会起作用 - 你最终会调用正确的方法,然后可以做你想要的。但是如果你创建了一个新的子类并且忘了添加方法,它就会默默地调用超类... ...
答案 1 :(得分:0)
只有一个实际的方法,所以无法知道你在源代码中指定了哪个类(没有阅读源代码)你可以做的是隐藏原始方法,虽然这通常是一个坏主意。
如果您想使用该类创建该类型的汽车,您可以使用构造函数
Car car = new Ferrari();
答案 2 :(得分:0)
如前所述,目前尚不清楚您想要实现什么,也许您应该重新设计代码。
与您的代码类似(据我所知),类似于:
Ferrari ferrari = Car.create(Ferrari.class);
可以通过以下简单示例实现:
/**
* @author ben
*/
public class TestClass
{
public abstract static class Car<E> {
private Car() {}
protected abstract void build();
@Override
public String toString() {
return getClass().getSimpleName();
}
public static <E extends Car> E create(Class<E> p_class) throws Exception {
E car = p_class.newInstance();
car.build();
return car;
}
}
public static class Ferrari extends Car<Ferrari> {
protected Ferrari(){};
@Override
protected void build() {
//your bunch of code ...
}
}
public static class Mercedes extends Car<Mercedes> {
protected Mercedes(){};
@Override
protected void build() {
//your bunch of code ...
}
}
public static void main(String[] args) throws Exception {
Ferrari ferrari = Car.create(Ferrari.class);
Mercedes mercedes = Car.create(Mercedes.class);
System.out.println("CAR1:" + ferrari);
System.out.println("CAR2:" + mercedes);
}
}
但是还有很多其他的方式...... 如上所述,目前尚不清楚你想做什么。
干杯。