我正在深入研究Java 8的创新,我正在尝试调用我在高级接口中实现的默认方法,即使子类重写它也是如此。我可以毫不费力地回到Comparator
课程中实现BusinessLogic
,但我想知道是否有一些魔法可以让我使用漂亮的新::
。
代码:
public interface IdEntity extends Comparable<IdEntity> {
int getId();
@Override
default int compareTo(IdEntity other) {
return getId() - other.getId();
}
}
public class Game implements IdEntity {
@Override
public int compareTo(IdEntity o) {
if (o instanceof Game) {
Game other = (Game) o;
int something;
// logic
return something;
}
return super.compareTo(o);
}
}
public class BusinessLogic {
private void sortList(List<? extends IdEntity> list) {
// for Game, Game::compareTo gets called but I want, in this call only, the default method
Collections.sort(list, IdEntity::compareTo);
}
}
答案 0 :(得分:6)
一种方法是将compare方法放在静态方法中:
public static interface IdEntity extends Comparable<IdEntity> {
int getId();
@Override default int compareTo(IdEntity other) {
return defaultCompare(this, other);
}
static int defaultCompare(IdEntity first, IdEntity second) {
return first.getId() - second.getId();
}
}
然后你的方法是:
Collections.sort(list, IdEntity::defaultCompare);
答案 1 :(得分:5)
更简单的方法:静态导入Comparator.comparingInt
并使用
Collections.sort(list, comparingInt(IdEntity::getId));
我不相信你可以重新提取默认的compareTo
实现:它被覆盖了;您通常无法运行重写方法实现。但这只会直截了当。
答案 2 :(得分:2)
一些一般性说明:
如果某个类重写了超类方法,则其他类无法有意调用超类方法,即忽略此方法已被覆盖的事实。禁止这种绕过是Java编程语言的基本设计决定。
唯一可以显式调用重写方法的类是执行覆盖的类,当然也只是在自身的实例上。因此,在Game.compareTo
中,您可以使用IdEntity.compareTo
调用被覆盖的IdEntity.super.compareTo
,this
将调用super
实例上的方法。
您也可以创建对此this
调用的方法引用,但由于它仅在this
实例上允许,因此Game
实例必须绑定且不能是功能签名。例如。在ToIntFunction<IdEntity> f=IdEntity.super::compareTo;
的实例方法中,您可以写:
default
此函数将调用当前IdEntity.compareTo
实例上的Game
方法IdEntity
,并通过abstract
参数。
但整个设计应该受到质疑。您永远不应该创建一个类层次结构,其中覆盖了履行compareTo
契约的非Comparable
Comparator
方法。这是一种反模式,会导致错误和令人惊讶的行为。作为Louis Wasserman has pointed out,可以轻松地为所需行为创建Game
。如果IdEntity
个实例的自然顺序与一般Comparator
顺序不同,则其中至少有一个不是“自然顺序”,因此应仅表示为import java.util.Comparator;
public interface IdEntity /* not Comparable<IdEntity> */ {
int getId();
static Comparator<IdEntity> defaultOrder() {
return Comparator.comparingInt(IdEntity::getId);
}
}
,甚至可能两者。
Game
如果您认为public class Game implements IdEntity,Comparable<Game> {
public int compareTo(Game o) {
int something;
// logic
return something;
}
// …
}
拥有自然顺序:
Game
或默认IdEntity.defaultOrder()
订单只是import java.util.Comparator;
public class Game implements IdEntity {
public static Comparator<Game> defaultGameOrder() {
return (a,b) -> {
int something;
// logic
return something;
};
}
// …
}
的替代选择:
<h1>Isotope - combination filters</h1>
<div class="filters">
<div class="ui-group">
<h3>Color</h3>
<div class="button-group js-radio-button-group" data-filter-group="color">
<button class="button is-checked" data-filter="">any</button>
<button class="button" data-filter=".red">red</button>
<button class="button" data-filter=".blue">blue</button>
<button class="button" data-filter=".yellow">yellow</button>
</div>
</div>
<div class="ui-group">
<h3>Size</h3>
<div class="button-group js-radio-button-group" data-filter-group="size">
<button class="button is-checked" data-filter="">any</button>
<button class="button" data-filter=".small">small</button>
<button class="button" data-filter=".wide">wide</button>
<button class="button" data-filter=".big">big</button>
<button class="button" data-filter=".tall">tall</button>
</div>
</div>
<div class="ui-group">
<h3>Shape</h3>
<div class="button-group js-radio-button-group" data-filter-group="shape">
<button class="button is-checked" data-filter="">any</button>
<button class="button" data-filter=".round">round</button>
<button class="button" data-filter=".square">square</button>
</div>
</div>
</div>
<div class="grid">
<div class="color-shape small round red"></div>
<div class="color-shape small round blue"></div>
<div class="color-shape small round yellow"></div>
<div class="color-shape small square red"></div>
<div class="color-shape small square blue"></div>
<div class="color-shape small square yellow"></div>
<div class="color-shape wide round red"></div>
<div class="color-shape wide round blue"></div>
<div class="color-shape wide round yellow"></div>
<div class="color-shape wide square red"></div>
<div class="color-shape wide square blue"></div>
<div class="color-shape wide square yellow"></div>
<div class="color-shape big round red"></div>
<div class="color-shape big round blue"></div>
<div class="color-shape big round yellow"></div>
<div class="color-shape big square red"></div>
<div class="color-shape big square blue"></div>
<div class="color-shape big square yellow"></div>
<div class="color-shape tall round red"></div>
<div class="color-shape tall round blue"></div>
<div class="color-shape tall round yellow"></div>
<div class="color-shape tall square red"></div>
<div class="color-shape tall square blue"></div>
<div class="color-shape tall square yellow"></div>
</div>