gpt4 book ai didi

java - 有没有办法用比这更少的代码扩展现有的接口(interface)实现?

转载 作者:行者123 更新时间:2023-12-01 09:14:50 26 4
gpt4 key购买 nike

关闭。这个问题是opinion-based .它目前不接受答案。












想改进这个问题?更新问题,以便 editing this post 可以用事实和引用来回答它.

5年前关闭。




Improve this question




假设我们有一个名为“C1”到“Cn”的接口(interface)“I”和“I”的n个实现。让我们进一步假设接口(interface)和实现驻留在无法更改的外部库中。最后,假设我们使用的是 Java 8。
现在我们要扩展“I”的所有实现的功能。
如果“I”是可变的,我们可以简单地添加具有默认实现的新方法,就像 Oracle 推出流 API 所做的那样。不幸的是,“我”是不可改变的。
我目前的解决方案如下:
创建一个新接口(interface)“IX”,它扩展“I”并包含所需的新方法作为它的默认实现。
因为“C1”到“Cn”没有实现“IX”而是“I”,我们需要实现“CX1”到“CXn”来利用新功能。这是我不喜欢的部分。我更喜欢一种像匿名类一样动态创建实现的方法。
以下是一些代码示例来说明我的方法:

// Instantiate existing "C9" implementation of "I"
I object = new C9();

// Definition of interface "IX"
public interface IX extends I {
default void newMethod() {
// Do something
}
}

// Example definition of implementation "CX9"
// Off course, this needs to be done for all "C1" to "Cn".
public class CX9 extends C9 implements IX {}

// Instantiate extended implementation "C9"
IX object = new CX9();

因为“CX1”到“CXn”的定义根本不需要任何主体实现,我考虑了那些样板文件并想摆脱它们。我实际上更喜欢以下内容。
IX object = new (C9 implements IX)() {};

当然,这不是有效的 Java 代码。这个想法是创建一个匿名类,它基于实现附加接口(interface)(“IX”)的现有类(“C9”)。有没有办法用标准Java做到这一点?
我绝对想用标准的 Java 做到这一点,而不需要字节码操作。当然,我可以使用包装器或动态代理,但“I”和“C”定义了很多方法。因此,我最终会得到更多样板代码。
我承认这个问题纯粹是学术问题,因为最终它是关于每个“I”的实现只删除一行代码。但我仍然对可能的解决方案感兴趣。
如果您喜欢更实用的方法,假设您想在一组未知的实现上强加流 API 之类的东西,而无需更改底层接口(interface)。
感谢您对此的意见。

最佳答案

解决此类问题的标准方法是委托(delegate)。由于我们对您的 I 一无所知也不是 C1 .. C9类型,我将使用一个众所周知的接口(interface)进行演示:

public interface ExtSet<T> extends Set<T> {
default T reduce(BinaryOperator<T> op) {
Iterator<T> it = iterator();
T t=it.next();
while(it.hasNext()) t=op.apply(t, it.next());
return t;
}
public static <T> ExtSet<T> enhance(Set<T> set) {
if(set instanceof ExtSet) return (ExtSet<T>)set;
final class Enhanced extends AbstractSet<T> implements ExtSet<T> {
public Iterator<T> iterator() { return set.iterator(); }
public int size() { return set.size(); }
public boolean contains(Object o) { return set.contains(o); }
public boolean add(T e) { return set.add(e); }
public boolean remove(Object o) { return set.remove(o); }
}
return new Enhanced();
}
}

委托(delegate)实现必须比具有可能为空的主体的扩展类做更多的工作,但它只需要做一次并且将与所有接口(interface)实现一起工作,甚至不知道它们,即
ExtSet<String> set1=ExtSet.enhance(new TreeSet<>());
Collections.addAll(set1, "foo", "bar", "baz");
System.out.println(set1.reduce(String::concat));

ExtSet<Integer> set2=ExtSet.enhance(new HashSet<>());
Collections.addAll(set2, 100, 42, 7);
System.out.println(set2.reduce(Integer::sum));

ExtSet<Thread.State> set3=ExtSet.enhance(
EnumSet.of(Thread.State.TERMINATED, Thread.State.NEW));
System.out.println(set3.reduce(BinaryOperator.minBy(Comparator.naturalOrder())));

这类似于 checkedSet , synchronizedSet , 和 unmodifiableSet 增强(或限制)现有的 Set执行。

关于java - 有没有办法用比这更少的代码扩展现有的接口(interface)实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40633631/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com