我知道这是一个非常简单的问题,但我已经在Python工作了很长时间,现在我必须回到Java,我似乎有问题更改芯片和围绕Java的基本多态性。
是否有可能覆盖(实现,确切地说)一个类' Java中的abstract
方法使用其中一个继承的类作为参数?
让我用一个非常简单的例子来解释(跟随"差不多官方" example的形状)
class Shape {}
class Circle extends Shape {}
class Triangle extends Shape {}
abstract class ShapeDrawer {
abstract void draw(Shape s);
}
class CircleDrawer extends ShapeDrawer {
void draw(Circle c){
System.out.println("Drawing circle");
}
}
有没有办法让Java将draw
类中的CircleDrawer
方法识别为draw
中抽象ShapeDrawer
的实现? (Circle
类毕竟从Shape
延伸
否则就说:我喜欢的是draw
类的CircleDrawer
方法只接受Circle
类型的实例,但同时,我&#39 ; d想告诉Java编译器void draw(Circle c)
实际上是位于其父类中的抽象方法abstract void draw(Shape s)
的实现。
提前谢谢。
答案 0 :(得分:7)
您可以通过泛型来解决您的问题:
public abstract class ShapeDrawer<T extends Shape> {
public abstract void draw(T shape);
}
public class CircleDrawer extends ShapeDrawer<Circle> {
public void draw(Circle circle) { ... }
}
答案 1 :(得分:4)
你不能,而且你有充分的理由不能解决问题。拿这个宣言
public abstract class ShapeDrawer {
public abstract void draw(Shape s);
}
现在接受一些收到ShapeDrawer
并尝试使用它的代码:
public void foo(ShapeDrawer drawer, Shape shape) {
drawer.draw(shape);
}
此代码应该有效,因为ShapeDrawer
的声明承诺任何实现它的人都会提供一个名为draw()
的方法,并且该方法可以处理任何Shape
。
但如果你被允许这样做:
public class CircleDrawer extends ShapeDrawer {
public void draw(Circle c) {...}
}
这将不再适用,您的CircleDrawer
将无法满足它可以处理任何Shape
的承诺。
但想象一下这个宣言:
public abstract class ShapeCreator {
public abstract Shape create();
}
public class CircleCreator extends ShapeCreator {
public Circle create() {...}
}
这会有用吗?
是的,它会(假设您使用Java 5或更高版本),因为与第一个声明不同,ShapeCreator
承诺的是它将有一个名为create()
的方法,它将返回一个{ {1}}。由于Shape
是Circle
,Shape
的子类可以决定仅返回ShapeCreator
,因此不会违反任何承诺。
那么你如何实现自己想要的目标呢?见loonytune's answer:)
答案 2 :(得分:1)
不,Java方法签名必须完全匹配,您不能使用子类型,否则您将重载方法而不是覆盖它。
你可以返回一个子类型,但就是这样,返回类型不是方法签名的一部分。
答案 3 :(得分:1)
从技术上讲,但你可以针对你指定的功能进行黑客攻击。
public abstract ShapeDrawer {
public abstract void draw(Shape s);
}
public CircleDrawer extends ShapeDrawer {
public void draw(Shape s){
if (s instanceof Circle) {
System.out.println("Drawing circle");
}
}
}