Java:覆盖 类 中不需要的方法 - 更新

Java : Override not needed methods inside classes - Update

在我的项目中,我有一个抽象 class,其中包含几个抽象方法。现在多个其他 classes 扩展了那个抽象 class。并非所有 classes 都想覆盖抽象 class 的所有方法,因为那对他们没有用。我如何在 subclasses 中提供那些对 class 没有用的方法的默认实现? 示例-:

public abstract class Animal
{
    public void Action()
    {
     .....
     this.roar();
    } 

    public abstract void roar();

    public abstract void run();
}

以上是抽象 class,它将具有子classes 将实现的抽象方法。

public class Lion extends Animal
{
   @Override
   public void roar()
   {
      s.o.p("Lion roars");
   }

   @Override
   public void run()
   {
      s.o.p("Lion runs");
   }
}

public class Deer extends Animal
{
   @Override
   public void roar()
   {
      // Question : What should I do here?
   }

   @Override
   public void run()
   {
      s.o.p("Deer runs");
   }
}

编辑-:

感谢您的建议,我理解有另一个 class 的想法,它可以具有不常见的方法(在这种情况下为 "roar")。但是我的项目结构有点不同并且它有点遗留代码,其中许多子 classes 从 Animal class 扩展而来。 Subclasses 调用具体方法,具体方法又调用抽象方法("roar" 在本例中,请参阅更新的 Animal class 和具体方法 "Action")。 现在按照你的建议,如果我创建另一个摘要 class

public abstract RoaringAnimal extends Animal
{
    public abstract void roar();
}

这将解决其中一个问题,因为我现在可以只扩展 RoaringAnimal 而不是 Animal 而其他 classes 调用 Animal.Action 方法,它们不会在内部找到 roar() 的实现Animal 和 javac 会报错。

如果您有适合子class但不适用于超级class的方法,例如此处的roar方法,那么您可能需要提供另一个摘要class subclass 是 Animal 但提供 roar,比方说 RoaringAnimalroar() 方法将不再在 Animal 中声明,而是在 RoaringAnimal.

中声明
public abstract class RoaringAnimal extends Animal
{
    public abstract void roar();
}

然后你可以让 Deer 扩展 Animal,而不是实现 roar(),但是你可以让 Lion 扩展 RoaringAnimal,实现 roar().

传统上你这样做:

   @Override
   public void roar()
   {
      throw throw new UnsupportedOperationException();
   }

这个异常实际上就是为了这个目的而创建的

@rgettman 的回答更合适!尽量不要使用这种方法 ;) 但知道它存在,你可以在 core Java libs

中找到一些例子

一个常见的解决方案是 classes 称为 Adapter classes。这些将使用标准(或空)实现来实现所有方法,并且您可以覆盖要更改的方法。缺点是,你不知道动物是否可以做这个或那个。

另一种可能性是将抽象 class 拆分为接口。通常组合在一起的每组方法都放在一个接口中。 class 然后将实现或不实现接口。这最终可能会为您的动物(咆哮,运行,爬行,...)提供功能接口,然后动物实现将实现它可以实现的接口。接口之间的依赖可以通过接口继承来建立。

在 Java8 上,可以使用接口的默认方法,也可以用于您的 classes。您不使用抽象基础class,而是使用具有默认方法的接口。

在这种情况下使用适配器 class。适配器 class 将是一个具体的 class,它扩展了您的抽象 class,但它基本上 什么都不用实现它的方法 或者它的方法实现可以抛出扩展 RuntimeException 的异常

在 Awt 中有一个很好的关于 MouseAdapter 的例子 class。 See the javadoc here

这是一个例子:

class AnimalAdapter extends Animal {

    @Override
    public void roar() {

        throw new NotImplementedException();

    }

    @Override
    public void run() {


    }

}

例如一只绵羊 class 将扩展 AnimalAdapter,但只有当它尝试调用 roar 时才会得到 RuntimeException。

class Sheep extends AnimalAdapter {

    @Override
    public void run() {
        System.out.println("I am a sheep I run, but I don't roar...");
    }

}

这种例外的例子

class NotImplementedException extends RuntimeException {

}