【问题标题】:Why can't I use the compare() method without making my class abstract?为什么我不能使用 compare() 方法而不使我的类抽象?
【发布时间】:2014-12-03 17:56:44
【问题描述】:

我目前正在尝试掌握继承和实现的窍门,但我无法理解为什么需要实现接口,以及为什么它们不仅仅是普通方法。 这是我目前正在编写的代码,它让我想到了这些问题,我正在尝试扩展 ArrayList 类,以便在输入时自动对元素进行排序。

import java.util.ArrayList;
import java.util.*;
import java.util.Comparator;
/**
 * extending to ArrayList
 */
public abstract class SortedArrayList<E> extends ArrayList<E> implements Comparator<E>
{

/**
 * Constructing the super
 */
public SortedArrayList()    
{
   super();

  }

  public  void insertAndSort (E element){
  if (isEmpty()){
      add(element);
    }

  for ( int i = 0; i < size(); i++){
      E otherElement = get(i);
      if(compare(element, otherElement) > 0){
          add(i+1, element);
        }
      if(compare(element, otherElement) < 0) {
          add(i-1, element);
        }
    }

}
}

注意:我知道扩展 arrayList 是不好的做法,这只是我必须做的事情。我也不允许使用 sort()。

我想使用比较器对 ArrayList 进行排序,所以我需要实现它。但是,它不会让我在不使类抽象的情况下实现它。我这样做了,尽管这意味着我不再遇到编译器错误,但我并不完全理解创建抽象类意味着什么以及它将产生什么影响。我在做正确的事吗? 谢谢。

【问题讨论】:

  • 当实现一个interface时,你必须实现它的方法(或者使实现类abstract
  • 您认为您目前在哪里实现了compare 方法?当您调用compare(element, otherElement) 时,您期望执行什么?不清楚为什么你决定实施Comparator,要么......
  • 对不起,我对此很陌生。我以为它在for循环中?我正在尝试遍历对象的数组列表并按升序对它们进行排序
  • 没有。如果你有一个非抽象类,你就不能使用 compare() 方法。

标签: java inheritance abstract-class comparator


【解决方案1】:

不,你没有做正确的事。您不应该声明Comparator 接口,而是在构造函数中获取它的实例。

abstract 修饰符意味着如果不提供compare 方法的实现,您就无法创建此类的实例,因此最后您必须实现该方法。如果它是一个单独的对象(您可以使用现有的实现),则它的可重用性更高。

编辑:(在这种情况下,组合优先于继承)

private final Comparator<E> comparator;
//constructor
SortedArrayList(Comparator<E> cmptor) {
   this.comparator = cmptor;
}

当你必须比较项目时,你可以使用comparator.compare而不是compare

【讨论】:

  • 如果我把它放在构造函数中,那是否意味着我不必在接口中声明它,不必使类抽象,随后我的 compare() 方法就可以工作了?
  • 用一个简单的例子更新了答案,如何将构造函数参数保存在字段中。
  • 顺便说一句:似乎您可能会过于频繁地添加新元素(最多与元素不为空时一样多),尽管我在这方面可能是错误的。
【解决方案2】:

您必须实现接口而不是仅仅在类中提供方法的原因是 java 可以帮助您以这种方式跟踪您的方法。

如果您只是实现该方法并稍有错误,如果没有接口,java 将不知道您在编译时尝试做什么,您必须等到运行时才能发现方法名称中的拼写错误,即使那样你也可能检测不到它。

仅检测到您有一个方法并允许调用者使用它的系统称为“Duck Typing”。有很多语言可以做到这一点,Java 只是为您提供了比鸭子类型的语言更多的帮助。

例如,如果您使用 Eclipse、NetBeans 或 IntelliJ 之类的 IDE(您绝对应该这样做,否则您无法利用 Java 的许多功能),编辑器/java 将引导您完成所需的步骤自动。

交互应该是这样的:

  • 您调用的方法采用 Comparitor 并传入一个对象。
  • Eclipse 给你一个错误,告诉你你的对象没有实现 Comparable
  • 您将“implements Comparable”添加到您的对象中。
  • Eclipse 告诉您“Comparable”对象不完整,因为它没有实现 compare 方法。它有一个灯泡,提供至少 2 个可行的解决方案:
  • 1) Eclipse 会将其设为“抽象”(表示该类尚未完成)
  • 2) Eclipse 将为您实现所需的方法
  • 您单击添加方法解决方案,它会添加整个方法签名,包括参数和返回值类型。
  • 您填写新方法的内部内容并完成。

这可能看起来有很多步骤,但具有以下优点:A) 即使您在每个步骤中都不确定,在您输入时总是会收到警告并提示您需要做什么——一个很大的节省时间!和 B) 一切都在编辑器中提供给您,一旦您知道了流程,您就不需要去文档来解决问题。

此过程适用于 Java 中的所有内容,即使使用外部库,您通常也可以在对库知之甚少或完全不了解的情况下进行编码,只需一个编辑器,并且接口是该过程的很大一部分。

如果您有兴趣了解您的 Java 类如何与 Duck Typing 一起使用,您可以下载 Groovy。 groovy 语言遵循并扩展了 Java,因此您可以使用相同的 java 类并通过 Groovy 运行它——但是您可以开始利用动态功能,例如 Duck Typing,您不需要实现接口,您只需实现方法和它的工作原理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-26
    • 1970-01-01
    • 2017-04-11
    • 2012-08-20
    相关资源
    最近更新 更多