在 Java 的抽象方法中使用继承的 类 识别方法的签名
Identify method's signature using inherited classes in Java's abstract methods
我知道这是一个很简单的问题,但我在Python工作了相当长的时间,现在我必须回到Java,我似乎有问题改变芯片 并围绕 Java 的基本多态性进行思考。
是否可以使用继承的 classes 之一作为参数覆盖(准确地说是实现)Java 中的 class' abstract
方法?
让我用一个非常简单的例子来解释(跟随 "almost official" 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 将 CircleDrawer
class 中的 draw
方法识别为 draw
中抽象 draw
的实现17=]? (毕竟 Circle
class 从 Shape
延伸)
否则:我想要的是 CircleDrawer
class 的 draw
方法只接受类型 Circle
的实例,但同时, 我想告诉 Java 编译器 void draw(Circle c)
实际上是位于其父 class.
中的抽象方法 abstract void draw(Shape s)
的实现
提前谢谢你。
你可以通过泛型来解决你的问题:
public abstract class ShapeDrawer<T extends Shape> {
public abstract void draw(T shape);
}
public class CircleDrawer extends ShapeDrawer<Circle> {
public void draw(Circle circle) { ... }
}
不,Java方法签名必须完全匹配,不能使用子类型,否则会重载方法而不是覆盖它。
您可以 return 一个子类型,但仅此而已,return 类型不是方法签名的一部分。
你不能,而且有一个很好的理由说明你不能。拿下这份声明
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()
的方法,这将 return 一个 Shape
。由于 Circle
是 Shape
,ShapeCreator
的子类只能决定 return Circle
,没有违反承诺。
那么你如何实现你想要的呢?参见 :)
从技术上讲不是,但您可以针对您指定的功能对其进行修改。
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");
}
}
}
我知道这是一个很简单的问题,但我在Python工作了相当长的时间,现在我必须回到Java,我似乎有问题改变芯片 并围绕 Java 的基本多态性进行思考。
是否可以使用继承的 classes 之一作为参数覆盖(准确地说是实现)Java 中的 class' abstract
方法?
让我用一个非常简单的例子来解释(跟随 "almost official" 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 将 CircleDrawer
class 中的 draw
方法识别为 draw
中抽象 draw
的实现17=]? (毕竟 Circle
class 从 Shape
延伸)
否则:我想要的是 CircleDrawer
class 的 draw
方法只接受类型 Circle
的实例,但同时, 我想告诉 Java 编译器 void draw(Circle c)
实际上是位于其父 class.
abstract void draw(Shape s)
的实现
提前谢谢你。
你可以通过泛型来解决你的问题:
public abstract class ShapeDrawer<T extends Shape> {
public abstract void draw(T shape);
}
public class CircleDrawer extends ShapeDrawer<Circle> {
public void draw(Circle circle) { ... }
}
不,Java方法签名必须完全匹配,不能使用子类型,否则会重载方法而不是覆盖它。
您可以 return 一个子类型,但仅此而已,return 类型不是方法签名的一部分。
你不能,而且有一个很好的理由说明你不能。拿下这份声明
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()
的方法,这将 return 一个 Shape
。由于 Circle
是 Shape
,ShapeCreator
的子类只能决定 return Circle
,没有违反承诺。
那么你如何实现你想要的呢?参见
从技术上讲不是,但您可以针对您指定的功能对其进行修改。
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");
}
}
}