使用Java的抽象方法中的继承类来识别方法的签名

时间:2015-05-26 22:32:16

标签: java oop inheritance abstract

我知道这是一个非常简单的问题,但我已经在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)的实现。

提前谢谢。

4 个答案:

答案 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}}。由于ShapeCircleShape的子类可以决定仅返回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");
        }
    }
}