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
,比方说 RoaringAnimal
。 roar()
方法将不再在 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 {
}
在我的项目中,我有一个抽象 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
,比方说 RoaringAnimal
。 roar()
方法将不再在 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 {
}