当前位置: 首页 > 知识库问答 >
问题:

抽象:可选方法?[java](建模过滤器)

商佑运
2023-03-14

对于我的任务,我需要对滤波器进行建模,例如基本级别的信号处理中的滤波器。滤波器可以采用任何类型的输入并输出不同类型的输入,如果滤波器是这样实现的。最简单的滤波器输出输入。其他示例滤波器是算术平均值、最大值或最小值滤波器,它返回最大输入。类似的滤波器只能返回最后N个输入的平均值/最大值/最小值。一些滤波器是可重置的,并且有一个方法“重置”,它接受相同类型的输入。例如,max3滤波器返回最后三个输入的最大数量,或者自上次重置以来,包括重置方法所接受的输入。该任务进一步详细描述了其他更复杂的过滤器,但我在最基本的抽象方面遇到了困难。

所以我的第一次尝试是创建一个接口“Filter”,它有一个方法“filter”。这将由过滤器实现,以满足他们自己的需求。我创建了一个抽象类“StorageFilter”,它存储了可以使用受保护的set/get方法访问的输入列表。然后,我扩展了该类,以在另一个抽象类“ResetableFilter”中实现重置函数。因此,无法重置的筛选器将扩展第一个抽象筛选器和可以重置第二个抽象筛选器的筛选器。但是我的实现并没有真正奏效,因为过滤器比这更复杂一些。有几种主要类型的过滤器,我可以确定。过滤器:

  • 存储一个输入,例如max/min过滤器:只需将存储值与输入进行比较,如果它是新的max/min,则将存储值设置为输入。我们将此类型称为1。
  • 存储输入列表,例如最后N个最大/最小值过滤器:仅存储最后N个输入,因此过滤器方法可以遍历列表并找到最大/最小值。我们将此类型称为2。(这也可以以另一种方式实现,存储两个值,一个表示当前最大/最小值及其“年龄”)
  • 存储输入列表和输出列表,例如使用方程的复杂标量线性滤波器,它们都用于计算新输出。我们将此类型称为3。
  • 根本不存储像第一个示例这样的简单过滤器或只返回两倍输入的过滤器。我们将此类型称为4

因此,过滤器可以存储许多类型的内容,但并不是所有的过滤器都可以重置。

我的一般问题是如何在保持抽象的同时实现可选方法?此类型(过滤器)可以具有其子类型可以具有的可选方法(重置)。我不能只是有一个空的方法“reset”,它什么都不做,但过滤器仍然能够调用。实现可选方法的最佳方法是什么,例如在这种情况下,同时保持抽象?

  • 使用@可选:使用此注解意味着不使用此方法的过滤器将抛出不支持的操作异常。这是一种可以接受的维护抽象的方法,因为Java的集合使用它,但由于涉及异常,它不可取。
  • 创建一个“重置”接口并让每个可以重置的过滤器实现它:这也很糟糕,因为它几乎会使我必须考虑的过滤器类型增加一倍。(即类型1过滤器、可重置的类型1过滤器、...和类型4过滤器。由于类型4过滤器不存储任何它们永远不会重置的东西)
  • 《代码完成2》一书描述了一个为Cat建模的场景。猫可以抓痒,但有些猫是有缺陷的,因此不能抓痒。为猫可以做或不能做的事情创建不同的类会使它变得复杂,因此您最终会得到像Scratchless Tailess... Cat这样的类。本书提供的解决方案是创建一个包含在Cat类中的内部类“爪”或构建一个包含猫是否抓痒的构造函数。由此我认为一个最佳解决方案是创建一个内部接口“ResetableContainer”,它具有一个方法重置,可以实现以适应不同的类型。它可以保存过滤器需要存储的任何内容,并且将根据存储的内容来实现重置。问题仍然是我如何实现它以避免所有这些复杂的存储可能性(单个输入或输入列表)?

共有2个答案

严斌
2023-03-14

这听起来像是学校的作业,所以你可能会受到限制,无法做到这一点,但我会做的是保持简单:一个界面:

public interface Filter<In, Out> {
    public Out filter(In toFilter);
    public void reset();
    public boolean canReset();
}

然后可能是一个抽象基类,为具有它们的方法提供良好的默认实现:

public abstract class BaseFilter<In, Out> implements Filter<In, Out> {
    public void reset() {}
    public boolean canReset() { return false; }
}

我甚至不会包括canReset,除非过滤器有时可以重置,有时不可以。如果这不是您想要支持的可能性,那么您可以删除canReset,只要在重置时调用reset(),如果它是可重置的过滤器。

霍襦宗
2023-03-14

看起来您遇到了一个概念设计问题,因为您希望<code>过滤器

您可以做的是创建这些“可选”方法,以便在执行时返回值:

/**
 * Resets the filter.
 *
 * @returns
 *          false if this operation is not supported by the filter
 */
public boolean reset() {
    return false;
}

一个更好的方法:包含包含一个必须被覆盖的附加方法,一个更常见的设计模式:请参阅这个问题的示例。如前所述,只有一个以上的接口可能也很好。

 类似资料:
  • 在与图书馆版本作斗争之后,我已经到了一个进退两难的地步。类似的问题似乎不适用,因为它已经三年了,我正在使用更新版本的东西,而且它抱怨

  • 我正在尝试对扩展抽象基的类进行单元测试。以下是“类似的类”,以供说明: 下面是我正在尝试的单元测试: 当我做这个测试的时候 java.lang.NullPointerException 在中 我知道自动连线的“滤水器”没有初始化。但接下来,我只想在我的单元测试中模拟抽象的“非抽象”方法。 我该如何使用EasyMock来实现这一点呢?另外,我不知道和应该做什么。

  • 所以我试图扩展一个employee抽象类。代码如下: 现在,正如您所看到的,我已经在两个子类中遍历了抽象方法getFeedback。但我得到了这个错误: 那么问题是什么呢?为什么在两个子类中都编写了getFeedback方法,却引发了这个错误

  • 问题内容: 我想编写一个抽象方法,但编译器始终显示此错误: 抽象方法不能有主体 我有这样的方法: 怎么了 问题答案: 抽象方法意味着没有默认实现,并且实现类将提供详细信息。 本质上,您将拥有 因此,它与错误状态完全相同:您的抽象方法不能具有主体。 在Oracle网站上有完整的教程,网址为:http : //download.oracle.com/javase/tutorial/java/IandI

  • 问题内容: Java 8接口默认方法与抽象类中的非抽象方法-两者之间是否有任何区别(除了iface-类,可见性等不同) 默认方法不是Java的后退一步,是否违反Java多年来宣传的本质? 问题答案: 如果抽象子类的具体子类被super()覆盖,则抽象类中的非抽象方法将被调用。因此,存在多种可能性。如果不重写method,则将执行超类方法。如果我们在具体的子类方法中使用super(),则将执行被超类

  • Java 8接口默认方法与抽象类中的非抽象方法--两者之间有什么区别吗(除了iface-class、可见性等的区别之外) 默认方法是不是在Java中倒退了一步,意味着它违背了Java多年来宣传的本质?!