改变java中子类方法的语义
我最近学习了 3 种新语言,但我开始对它们感到困惑。几年来我没有使用 Java 做过任何特别复杂的事情(除了 Android 之外)。我很难记住这是否可能:
我主要是对 ArrayList 进行子类化,这样我就可以保持 arraylist 的有序。我正在尝试重写 add(object)
方法,但我希望它返回一个 int 而不是布尔值(添加的对象的位置)。但我的方法的返回类型出现错误。
我想要的东西在语言中是可能的吗?子类中的方法可以返回与超类方法不同的东西吗?
或者我想做一些愚蠢的事情?这是否打破了继承的is-a
思想?我应该封装一个数组列表而不是扩展它吗?
作为参考,我正在尝试做的一部分:
public class AuthorArray extends ArrayList \{
@Override
public int add(Author object) {
super.add(object);
Collections.sort(this, new SortByLastName());
return this.indexOf(object);
}
}
I've recently learned like 3 new languages and I'm starting to get them confused. I haven't worked Java in doing anything particularly complex (outside of android) in a couple years. I'm having trouble remembering if this is possible:
I'm subclassing ArrayList mainly so I can keep the arraylist ordered. I'm trying to override the add(object)
method but I want it to return an int instead of a boolean (the location of the object that was added). But I'm getting errors on the return type of my method.
Is what I want even possible in the language? Can you have a method in a subclass return something different than the superclass' method?
Or am I trying to do something stupid? Is this breaking the is-a
idea of inheritance? Should I just encapsulation an arraylist instead of extending it?
For reference, a portion of what I'm trying to do:
public class AuthorArray extends ArrayList \{
@Override
public int add(Author object) {
super.add(object);
Collections.sort(this, new SortByLastName());
return this.indexOf(object);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
一般来说,没有。唯一的例外是协变返回类型,即当重写方法返回基类/接口方法中返回类型的子类时。这在 Java5 中成为可能,并且是一个很好的实践。但你的情况不属于这一类。
是。
ArrayList
的用户期望从add
获得一个boolean
返回值,并按照他们添加元素的顺序查看元素,这样你就会中断那个期望。不要那样做。是的。然后,您可以使用您喜欢的任何合同来定义自己的界面。但首先,考虑使用
TreeSet
相反。In general, no. The only exception is covariant return types, when an overridden method returns a subclass of the return type in the base class/interface method. This became possible with Java5, and is good practice. But your case does not fall into this category.
Yes. Users of
ArrayList
expect to get aboolean
return value fromadd
, and see the elements in the same order they added them, and you would break that expectation. Don't do that.Yes. Then you can define your own interface, with whatever contract you prefer. But first, consider using a
TreeSet
instead.改变语义是不好的。在您的情况下,如果您想要一个简单的修复,将方法名称从
add
更改为myadd
可以解决您的问题。就我个人而言,我建议学习如何使用 Google guava-libraries 不可变的排序数据结构“功能”,要获得回顾概述,请浏览 youtube。
但在这里,我在标准 Java 中做了示例,说明如何使用 TreeSet 自动排序 - 自定义类、2 个值比较器和高效的二分搜索等效项。
这将输出:
Changing semantics is bad. In your case, changing method name from
add
tomyadd
would fix your problem, if you want a simple fix.Personally i would recommend learning how to use Google guava-libraries immutable, sorted data structures with 'function', to get a refresher overview, browse youtube.
But here in standard Java, I made example, how to use TreeSet autosort - custom class, 2 value comparator, and efficient binary search equivalent.
This will output:
List 接口保证元素将按照添加的顺序返回。因此,如果只有一个线程操作列表,您可以轻松地执行添加操作,然后请求其大小。 size - 1 是元素的序数值。
如果上述顺序不是您想要的,那么您有两种选择 - 要么使用 Collection.sort() 方法对列表进行排序,要么使用 SortedSet。两种方法都可以使用比较器。
我从未发现有必要扩展 Java 集合框架,并且不建议您在这种情况下这样做。
The List interface guarantees that elements will be returned in the same order that they are added. Thus if you only have one thread manipulating the list you can easily perform an add and then request its size. size - 1 is the ordinal value of the element.
If the above order is not what you want then you have two choices - either sort the list using Collection.sort() methods, or use a SortedSet. Both methods can take on a comparator.
I've never found the need to extend the Java collections framework and do not recommend that you do so in this circumstance.