繁体   English   中英

多态最佳实践

[英]Polymorphism best practice

我一直在研究java设计模式以使我的项目更有条理,我需要知道的一件事情是,如果以下方法是一种好的做法。

使用父抽象类或接口时,子类的方法在父中定义。

我的问题是,当我有很多子类时,如果每个子类都覆盖父类中的方法A,但是其中一个子类需要具有不同的方法B,那么即使在父类中定义方法B也是一种好习惯,即使它仅用于该单个子类。

这就带来了一个问题,即使从未从该类中调用过methodB,也需要在每个子类中使用它。

我是要这样做吗? 似乎不正确。

代码示例:

public interface Parent{

  public void methodA();

  //Should this method be in the parent as it is only used once?
  public void methodB();

}

子类:

public class First implements Parent{

  @Override
  public void methodA(){
    System.out.println("This is method A");
  }

  // Does Nothing but java must have it used in the sub class
  @Override
  public void methodB(){
    throw new UnsupportedOperationException("Do not call methodB from class First!!");
  }
}



public class Second implements Parent{

@Override
  public void methodA(){
    System.out.println("This is method A");
  }

  // methodB is being used for this sub-class
  @Override
  public void methodB(){
    System.out.println("This is method B");  
  }

}

从上面的代码中可以看到,我仅对第二个子类使用methodB,但是仍然需要在第一个子类中使用它,否则会引发异常。 由于永远不要在第一个类中调用此方法,因此我只是抛出一条带有消息的异常。 这似乎是无组织的。 使用继承绝对是错误的。

如果我仅在第二类中使用methodB而不将其添加到父类中:

 public static void main(String[] args) {
   Parent p = new Second();
   p.methodA() // Prints "This is method A"
   p.methodB() // throws an error
 }

有谁知道我如何调用类中的特定方法而不会引发错误。 将方法添加到父级绝对是不好的做法。

编辑:

感谢您的所有快速回复,我发现执行此操作的方法是定义不同的接口:

interface X {
  public void A()
}

interface Y extends X {
  public void B()
}

class First implements X {
  @Override
  public void A();
}

class Second implements Y {
    @Override
    public void A();

    @Override
    public void B();
}

如果仍然不正确,请告诉我。

interface是实现它的类同意履行的契约。

考虑一个名为Furniture的假设接口。 并非所有的Furniture都会合理地实现recline()方法(例如表格),但是有些可能。 这是一个很好的示例,为什么recline()方法不应在此接口中,而应在扩展接口RecliningFurniture

这样, Table类的对象将实现FurnitureChair类的对象可能将实现RecliningFurniture 两者都将受Furniture接口合同的约束,但Chair也必须履行该合同RecliningFurniture的附加条款。

[...]在父方法中定义方法B是个好习惯,即使它仅用于单个子类。

当然不。

想象一下,如果每个超类都添加自己的子类,那么超类将以多快的速度增长。 每个孩子都有一堆其他子类需要的无关的东西。 它指示类之间的关系不正确以及继承的错误用法。

在您的代码段中,类之间的关系不明确。 继承总是需要真实的例子。 在这里,我不能说First Parent

对于几乎所有子类都将要实现的方法,我已经看到了一种使用默认的基于异常的实现在父级中定义该方法的实践。 因此,您无需在子类中复制标准行为。

这将对您当前的状况有所改善:

default void methodB() {
     throw new UnsupportedOperationException("[...]");
}

Parent实例传递给方法时,请确保仅使用此类提供的接口。 这样一来,您就不必投放和破坏其界面。

A -> [methodA] (only)
B -> [methodB] (only)
C -> [methodA, methodB]

如果给定的方法还不够,请创建一个复合接口,该接口将添加错过的方法:

interface A { void methodA(); }
interface B { void methodB(); }
interface C extends A, B {}

class First implements A { ... }
class Second implements C { ... }

如果某些对象的行为类似于X,而其他对象的行为类似于X +,则您需要2个接口,因为您有2个事物,其中一个与另一个相似,另加一些

interface X {
      public void A()
}

interface Y extends X {
      public void B()
}

class First implements X {
      @Override
      public void A();
}

class Second implements Y {
      @Override
      public void A();
      @Override
      public void B();
}

可以肯定,在需要X的情况下,所有对象的行为都将像X。 在其他情况下,您将不得不提到这里我们还有更多

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM