我目前正试图获得继承和实现的悬念,但我无法理解为什么我需要实现接口,以及为什么它们不仅仅是常规方法。 下面是我正在编写的代码,它将我带到了这些问题,我正在尝试扩展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进行排序,因此我需要实现它。但是,如果不将类抽象化,它就不会让我实现它。我这样做了,虽然这意味着我不再遇到编译器错误,但我并不完全理解制作抽象类的含义以及它将产生什么影响。我做对了吗? 感谢。
答案 0 :(得分:0)
不,你没有做正确的事。您不应该声明Comparator
接口,而是在构造函数中获取它的实例。
abstract
修饰符意味着如果不向compare
方法提供实现,则无法创建此类的实例,因此最后您必须实现该方法。如果它是一个单独的对象(您可以使用现有的实现),它更可重用。
编辑:(在这种情况下,组合优先于继承)
private final Comparator<E> comparator;
//constructor
SortedArrayList(Comparator<E> cmptor) {
this.comparator = cmptor;
}
当您必须比较项目时,您可以使用comparator.compare
代替compare
。
答案 1 :(得分:0)
你必须实现界面而不是仅仅在类中提供方法的原因是java可以帮助你以这种方式跟踪你的方法。
如果您只是实现该方法并且稍微有点错误,没有接口java就不知道您在编译时尝试做什么,您必须等到运行时才能发现错误拼写错误在方法名称中,即使这样,您也可能无法检测到它。
一个只检测到你有一个方法并允许调用者使用它的系统叫做#34; Duck Typing&#34;。有很多语言可以做到这一点,Java只是为你提供了比鸭子打字的语言更多的帮助。
例如,如果您使用的是Eclipse,NetBeans或IntelliJ等IDE(您绝对应该这样,否则您无法利用Java的许多功能),编辑器/ java将引导您完成这些步骤你需要自动。
互动应该是这样的:
这可能看起来像很多步骤,但具有以下优点:A)即使您不确定每一步,您也会在键入时始终收到警告,并提示您需要做什么 - 一个大的节省时间!和B)在编辑器中提供了所有内容,一旦您知道该过程,您就不需要去文档来解决问题。
这个过程适用于Java中的所有内容,即使使用外部库,您也可以在很少或根本不知道库的情况下编写代码,只需编辑器,接口就是该过程的重要部分。
如果您有兴趣了解Java类如何与Duck Typing一起使用,您可以下载Groovy。 groovy语言遵循并扩展Java,因此你可以使用相同的java类并通过Groovy运行它 - 但是你可以开始利用像Duck Typing这样的动态功能,你不需要实现接口,你只需要实施该方法,它的工作原理。