考虑以下代码,该代码摘录了LinkedList<E>实现List<E>和的实际用例Deque<E>。
可以看到,两个接口都有一个size()和isEmpty()方法,其中isEmpty()可以将方法默认为size()。
因此,让我们(使用虚拟接口)进行操作,因为Java 8尚未这样做:
interface List<E> {
public int size();
default public boolean isEmpty() {
return (size() == 0);
}
//more list operations
}
interface Deque<E> {
public int size();
default public boolean isEmpty() {
return (size() == 0);
}
//more deque operations
}
class LinkedList<E> implements List<E>, Deque<E> {
private int size;
@Override
public int size() {
return size;
}
}
Run Code Online (Sandbox Code Playgroud)
糟糕!我们在上遇到了编译时错误LinkedList,因为它不知道isEmpty() …
Java 8 引入了接口默认实现的概念?这是否违反了开放封闭原则,因为基于https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html上的示例,您似乎始终可以打开界面以添加新功能?
architecture open-closed-principle default-implementation java-8 default-method
我有一个人员存储库,如下所示
@RepositoryRestResource
public interface PersonRepository extends Repository<Person, String> {
List<Person> findAll();
default List<Person> findNewPersons() {
return findByStartDateAfter(LocalDate.now().minusMonths(3));
}
List<Person> findByStartDateAfter(LocalDate date);
}
Run Code Online (Sandbox Code Playgroud)
我无法通过休息公开默认方法。有没有办法在不创建存储库实现的情况下做到这一点?
让 Functor 成为 Applicative 和 Monad 的超类有什么意义呢?据我所知,Applicative 和 Monad 都立即暗示了 Functor 唯一遵守法律的实现。但我每次都必须输入相同的 Functor 实现。有没有办法避免这样做?
更进一步,Monad 暗示了 Applicative 唯一遵守法律的实现,那么为什么要让 Applicative 成为 Monad 的超类呢?它再次使得为新数据类型实现 Applicative 变得多余。
有没有一种方法可以制作一个 Monad,而不必实现 Applicative 和 Functor(因为它的操作已经是最通用的)。并且无需实现 Functor 即可创建 Applicative。
我看到了类层次结构的好处,因为我刚才所说的解释了它们之间的“是”关系。但同时必须实现每一个都是烦人的。我只想定义returnand>>=并获取所有 3 个操作的所有操作。
我不明白为什么下面的示例会抛出 IllegalAccessError 异常。foo()中的方法Parent不能被 继承Child,因为它是私有的。但尝试调用默认方法foo()会导致异常。
public class Parent {
private void foo() {
System.out.println("Parent-foo");
}
}
interface Boo {
default void foo() {
System.out.println("Boo-foo");
}
}
class Child extends Parent implements Boo {
public static void main(String[] args) {
new Child().foo(); // runtime IllegalAccessError;
}
}
Run Code Online (Sandbox Code Playgroud) 考虑到接口现在可以为它提供的方法提供实现,我无法正确理解接口和抽象类之间的差异.有谁知道如何正确解释差异?
我还被告知,与抽象类相比,接口稍微更轻,性能明智.有人能证实吗?
所以我们有默认方法,也被称为防御方法和'虚拟扩展方法'.
虽然我很欣赏默认方法的巨大价值(在某些方面甚至比它们的C#对应物更强大)但我想知道什么是允许扩展现有接口而不访问其源代码的决定.
在他的一个答案中, Brian Goetz提到默认方法是为了方便和界面演变而设计的.因此,如果我们编写一个接口,我们可以在那里填充我们通常必须放在一个单独的类中的各种实用方法.那么为什么不加倍努力并允许它不受我们控制的接口?
我想使用java 8新的默认方法重构模板方法.假设我在抽象类中定义了一个流程:
public abstract class FlowManager{
public void startFlow(){
phase1();
phase2();
}
public abstract void phase1();
public abstract void phase2();
}
Run Code Online (Sandbox Code Playgroud)
我有几个子类扩展上面的流管理器,每个子类实现自己的phase1和phase2mathod.我想知道将代码重构为这样的接口是否有意义:
public interface FlowManager{
public default startFlow(){
this.phase1();
this.phase2();
}
public void phase1();
public void phase2();
}
Run Code Online (Sandbox Code Playgroud)
你怎么看?
最近我遇到了这段代码.
public interface CustomerQueryService {
default Customer getCustomerById(long id) {
throw new NotImplementedException();
}
}
Run Code Online (Sandbox Code Playgroud)
后来,事实证明这是该项目的一般惯例.这被认为是一种好习惯吗?
我举一个例子来设置一些上下文,所以我有两个接口,每个接口继承相同的父接口并定义它们自己的父接口的抽象方法的实现.
interface A
{
Set a();
}
interface B extends A
{
@Override
default Set a()
{
return null;
}
}
interface C extends A
{
@Override
default Set a()
{
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
在一个名为的接口中D,该实现创建了一个匿名内部类,然后需要调用超类型(B和C)a()实现.
interface D extends B, C
{
@Override
default Set a()
{
return new HashSet()
{
{
final int totalSize = D.this.B.super.a().size() + D.this.C.super.a().size();
}
};
}
}
Run Code Online (Sandbox Code Playgroud)
问题是表达式D.this.B.super.a()并D.this.C.super.a()没有成功编译,所以是什么?
谢谢你的努力.
default-method ×10
java ×7
java-8 ×6
interface ×3
api-design ×1
applicative ×1
architecture ×1
exception ×1
functor ×1
haskell ×1
inheritance ×1
monads ×1