Java: 无法覆盖传递子类的抽象方法

Java: Cannot override abstract method passing subclass

我有一个摘要class

public abstract class SuperclassA{
   public abstract void method(SuperclassB b);
}

和一个实现

public class SubclassA extends SuperclassA{

   @override
   public void method(SubclassB b){
   }
}

其中 SubclassB extends SuperclassB.

我的 NetBeans 编辑抱怨我没有覆盖 method。 我该怎么做才能将 subclass 实际传递给 method

为了覆盖基 class 的方法,子 class 的方法必须具有相同的签名。

如果您希望覆盖的方法仅接受 SubclassB 的实例,您可以对其进行测试:

public class SubclassA extends SuperclassA
{
   @Override
   public void method(SuperclassB b){
       if (!(b instanceof SubclassB)) {
           // throw some exception
       }
       SubclassB sb = (SubclassB) b;
       ...
   }
}

您可以按如下方式调用该方法:

SuperclassA a = new SubclassA ();
a.method (new SubclassB ());

Actual, Method Signature is,

public abstract void method(SuperclassB b);// into abstract class

Your overrided Method Signature must be same, Otherwise it's not override, in fact it will be treated like overloading,

@override
   public void method(SuperclassB b){
   }

  //OverLoad not Override
   public void method(SubclassB b){
   }

SubclassA 中的方法采用 SubclassB 类型。 SuperclassA 中的方法正在接收 SuperclassB 的类型。您没有覆盖 parent class 方法,而是使用不同的类型进行重载。

根据您想要完成的目标,您可以试试这个

public class SubclassA extends SuperclassA{

   @override
   public void method(SuperclassB b){
   }
}

这将覆盖您想要的方法。只要 SubclassBSuperclassB 的 child,那么你仍然可以将 SubclassB 传入。

如果你愿意,你仍然可以有一个重载方法接受 Subclasss

public class SubclassA extends SuperclassA{

   @override
   public void method(SuperclassB b){
   }

   public void method(SubclassB b){
   }
}

查看 this thread 了解有关重载与覆盖的更多信息。

将 class 或接口的方法签名视为合同或承诺它和任何子 class 可以做什么。

SuperclassA 承诺对任何 SuperclassB 执行操作 method。为了使 SubclassA 成为 SuperclassA,它必须对 all SuperclassB 执行操作 method。问题是它只对 一些 类型的 SuperclassB 执行操作 method

这里是同样的情况,名字更容易理解。

abstract class Pet {
    // Pet methods
}

class Cat extends Pet {
    // Cat methods
}

class Dog extends Pet {
    // Dog methods
}

abstract class PetShop {
    public abstract void groom(Pet pet);
}

宠物店class承诺任何宠物店都可以为任何宠物美容,包括狗。

PetShop shop = new FranksPetShop();
shop.groom(new Dog());

如果我们像这样定义 FranksPetShop,那么它只定义了如何修饰猫的宠物,任何其他类型的宠物(包括狗)都没有定义。

class FranksPetShop {
    @Override
    public abstract void groom(Cat cat) {
        // Groom that cat
    }
}

要解决这个问题,FranksPetShop 必须定义如何修饰宠物而不仅仅是猫。

class FranksPetShop {
    @Override
    public abstract void groom(Pet pet) {
        // Groom that pet
    }
}

请参阅 override 上的 Oracle 文档页面。

An instance method in a subclass with the same signature (name, plus the number and the type of its parameters) and return type as an instance method in the superclass overrides the superclass's method.

subclass 覆盖方法的能力允许 class 从行为为 "close enough" 的 superclass 继承,然后将行为修改为需要。

The overriding method has the same name, number and type of parameters, and return type as the method that it override

在你的情况下,你没有使用相同的方法签名。

public void method(SubclassB b){

应该改为

public void method(SuperclassB b){

现在您可以使用 Eran 建议的解决方法 instanceof