【问题标题】:Is it possible to have specialized parameters in overridden methods?是否可以在覆盖的方法中有专门的参数?
【发布时间】:2010-10-23 15:36:02
【问题描述】:

假设我有一个名为“shape”的抽象父类,并且有多个子类(三角形、正方形、圆形...)。我想在父“shape”类中定义一个所有子类都必须实现的抽象方法,我们称之为“draw”。所以所有形状子类都必须提供“draw()”方法。但是,draw 方法采用“Stencil”类型的参数,而且,并非每个形状子类都可以使用任何模板...

所以有一个抽象的“形状”类、多个形状子类和多个模板。我需要一个在 shape 类中定义的 draw 方法。正方形可能使用 Stencil1,圆形可能使用 Stencil2。

我猜泛型可以解决问题,但我不确定。每个形状子类都需要使用特定的模板定义绘图方法,因为这些类也被其他类使用,编译器应该强制所有程序员使用该类支持的模板调用绘图方法。我们不能定义像“public abstract void draw(Stencil s)”这样的抽象方法,因为程序员可以将任何模板传递给 square 类,而 square 类只支持“Stencil1”

有什么想法吗?

更新1: 应该补充一点,形状类并不关心子类使用哪个模板,但由于子类也用于其他类,所以定义绘制方法很重要,以便编译器只接受支持的模板。

【问题讨论】:

  • 除了 shape 类确实关心,因为正如您所说,“编译器应该强制所有程序员使用该类支持的模板调用 draw 方法”
  • 不,形状类不关心;重要的是各种 Shape 类的其他用途。

标签: java abstract-class overriding


【解决方案1】:

如果您希望在编译时捕获它,请考虑以下选项:

  • 创建一组抽象模具。特别是如果您认为可以将它们分组。因此,如果您将有多个“方形”模板,请创建一个 SquareStencil 抽象类型并从中派生具体实例。您甚至可以将它们创建为抽象 Stencils 类的子集。
  • 重载draw方法。它没有必要是通用的。让编译器通过为工作选择正确的方法来帮助您。

【讨论】:

  • 如果我超载,那会使问题变得更糟,不是吗?我不想要多个版本的draw;我想要一个只接受该类正确模板的版本。
【解决方案2】:

我认为您可能应该重新考虑您的初始设计。

当然,您可以通过使用 instanceof 等来解决这个问题。但是,这会导致 API 非常混乱(如果您正在使用它)。

【讨论】:

  • 我敢肯定,从我的描述来看,这个设计听起来令人困惑,但它并没有那么糟糕
【解决方案3】:
public abstract class Shape<S extends Stencil>
{
   public abstract void draw( S stencil );
}

public class Square extends Shape<Stencil1>
{
   public void draw( Stencil1 stencil )
   {
     stencil.letsdo();
     stencil.some();
     stencil.drawing();
   }
}

public class Circle extends Shape<Stencil2>
{
   public void draw( Stencil2 stencil )
   {
      stencil.some();
      stencil.more();
      stencil.drawing();
   }
}

【讨论】:

  • draw的实现方法签名会不会和抽象方法draw的方法签名不一致?
  • 不,实际上。我刚刚在 Eclipse 中对此进行了测试以确保它工作正常。
  • 没有。 draw() 定义为采用 Stencil 类型或子类的 S。在 Square/Circle 中,您只需指定要使用的 Stencil 子类 - 因为它仍然是 Stencil,它不会与超类的方法签名冲突。
  • 谢谢,这正是我所追求的。
  • 这似乎有一些不好的副作用 - 例如,您无法绘制 List>.
【解决方案4】:

定义一个抽象模板,让子类构造函数决定使用哪个模板类。

private Stencil s;

public void draw(){
   privateDraw(s)
}

private abstract void privateDraw(Stencil s);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-28
    • 1970-01-01
    • 1970-01-01
    • 2021-05-24
    • 2014-01-10
    • 1970-01-01
    相关资源
    最近更新 更多