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

如何在实现接口但不扩展另一个类的Java类中引用超级方法?

孔鸿远
2023-03-14

我有几个Java类,它们扩展了泛型列表接口的各种实现。它们只需记录添加到列表中的任何内容。

LoggingArrayList如下所示。顾名思义,它扩展了ArrayList。LoggingLinkedList类完全相同,只是它扩展了LinkedList。

我的主要目标是避免重复所有的公共代码,这样我就可以使用不同的基类。我在尽量坚持干巴巴的原则(不要重复你自己)。

首先,请不要建议更好的登录方式。那根本不是我真正的申请。这只是一个简单的方法来演示我的问题。

我有两个密切相关的问题。第一个是题目中的问题。如何在实现接口但不扩展另一个类的Java类中引用“超级”方法?

如下所示的LoggingArrayList类工作良好,但当我将类声明从...extends ArrayList更改为...implements List时,对super.method()的三个引用就不再可以调用,这就是我的第一个问题。

对我的第二个问题的一个好的回答几乎会使第一个问题变得没有意义。第二个问题是这样的:有没有一种方法可以声明一个抽象基类或者一个接口,它可以通过各种add()方法的默认实现来扩展List,这样我就可以简单地扩展这个抽象基类或者实现那个接口,并且只指定什么类型的List将是具体类的基础?

例如,我想做这样的事情:

interface LoggingList<T extends Object, L extends List<T>> extends L
{
    // overloaded methods go here as shown below 
    //  with overloaded methods declared as default for the interface
}

...然后我可以简单地为List的每个具体实现实现一次LoggingList,而不重复所有的公共代码。具体的类可能看起来像这样,在它们的花括号内不需要额外的代码:

public class LoggingArrayList<T extends Object> implements LoggingList<T, ArrayList<T>> {}
public class LoggingLinkedList<T extends Object> implements LoggingList<T, LinkedList<T>> {}

问题是,我所提出的接口定义是无效的(无法编译),而且,下面所示代码中对super.method的引用是不可用的,除非我将LoggingList变成一个抽象子类而不是接口,然后我就回到了现在的位置。

提前感谢任何关于如何完成我的干燥目标的想法。

这是我的整个LoggingArrayList类。

public abstract class LoggingArrayList<T extends Object>
    extends ArrayList<T>
{
    protected void log(T e)
    {
        System.out.println(e == null ? "null" : e.toString());
    }

    @Override
    public boolean add(T e) {
        log(e);
        // How do I reference a super.method()
        // in a class that implements an interface
        // but does not extend another class?
        return super.add(e);
    }

    @Override
    public boolean addAll(Collection<? extends T> clctn) {
        boolean anyChanges = false;
        for(T e : clctn)
        {
            // ensure that we call our overridden version of add()
            //  so it gets logged.
            anyChanges = anyChanges || add(e);
        }
        return anyChanges;
    }

    @Override
    public boolean addAll(int i, Collection<? extends T> clctn) {
        for(T e : clctn)
        {
            // ensure that we call our overridden version of add() 
            //  so it gets logged.
            add(i, e);
            i++; // keep the inserted elements in their original order
        }
        return !clctn.isEmpty();
    }

    @Override
    public T set(int i, T e) {
        log(e);
        // How do I reference a super.method()
        // in a class that implements an interface
        // but does not extend another class?
        return super.set(i, e);
    }

    @Override
    public void add(int i, T e) {
        log(e);
        // How do I reference a super.method()
        // in a class that implements an interface
        // but does not extend another class?
        super.add(i, e);
    }
}

共有1个答案

房冥夜
2023-03-14

曾经的方法是:委派。

您可以只使用一个实现,而不是为不同类型的列表提供多个实现

public class LoggingList<T extends Object> implements List<T>

  protected List<T> superList;

  public LoggingList(List<T> anotherList) {
     superList= anotherList;
  }

  protected void log(T e) {
      System.out.println(e == null ? "null" : e.toString());
  }

  @Override
  public boolean add(T e) {
      log(e);
      return superList.add(e);
  }

然后调用super.而不是调用superlist.

您仍然必须将构造函数从new LoggingLinkedList()调整为new LoggingList()-但这应该不是什么大事...

 类似资料:
  • 问题内容: 在Java中,当接口扩展另一个接口时: 为什么要实现其方法? 当接口不能包含方法主体时,如何实现其方法 当扩展另一个接口而不实现它时,如何实现这些方法? 接口实现另一个接口的目的是什么? 这是Java的主要概念! 编辑: 在eclipse中,除了中的实现方法之外,还有实现符号。 当我将鼠标悬停在它上面时,它表示它实现了该方法!!! 问题答案: 为什么要实现其方法?当接口不能包含方法主体

  • 我有一个泛型类型K,我想验证K是否实现了接口可比性。这是我的代码: 但是代码不起作用。我不想将所有K限制为实现可比性。我已经有了另一个TreeMapVector相似度类。如果K实现了接口可比性,我将使用TreeMapVector相似度类返回结果。 你认为我如何能解决这个问题?谢了。

  • 问题内容: 我在编写的程序中遇到接口问题。我想创建一个接口,该接口的方法之一可以接收/返回对自己对象类型的引用。就像这样: 我不能在“?”处使用“ I”,因为我不想返回对接口的引用,而是要返回对类的引用。我搜索后发现在Java中没有“自我引用”的方法,因此我不能仅用“?”代替。在示例中,“ self”关键字或类似的内容。实际上,我想出了一个解决方案 但这似乎确实是一种解决方法或类似方法。还有另一种

  • 问题内容: 我有以下类和接口: 我想创建一个方法,其中参数需要为BasicObject类型并实现CodeObject。我尝试了以下代码,但不能保证clazz是实现CodeObject的类。 我想做这样的事情,但不能编译: 问题答案: 您的模式类必须扩展和扩展/实现(实际上是一个接口)。您可以使用方法签名的通配符定义中声明的多个类来执行此操作,如下所示: 请注意,如果您通过以下任何一种方式进行操作,

  • 我有以下类和接口: 我想创建一个方法,其中参数需要是BasicObject类型,并实现CodeObject。我尝试了以下代码,但它不能保证clazz是一个实现CodeObject的类。 我想做这样的事情,但它无法编译:

  • 我有个Z接口。它是由Y类实现的。我有另一个继承类Y的类x。因为y实现了类z指定的契约,所以x做同样的事情,因为它扩展了类y。因此,它是否也应该实现接口Z?