gpt4 book ai didi

java - 扩展泛型类时如何传递多个泛型参数

转载 作者:行者123 更新时间:2023-11-29 05:32:14 25 4
gpt4 key购买 nike

以下内容不会编译,但我希望创建一些可以编译的类似功能:

public class FreezerTest
{
interface Edible{}
interface SmallerThanABeachball{}
interface Freezeable{}
abstract class BoxedItem
{}
class Marbles extends BoxedItem
{}
class IceCream extends BoxedItem implements Freezeable, SmallerThanABeachball, Edible
{}
class MyBrother
{}
class Banana implements Edible, SmallerThanABeachball
{}
class Cat implements SmallerThanABeachball
{}

abstract class StorageChest<T>{
public void add(T toStore){}
}

class MiniFoodFreezer extends StoreageChest<Freezeable & Edible & SmallerThanABeachball>{
}

public FreezerTest(){
MiniFoodFreezer freezer = new MiniFoodFreezer();
freezer.add(new Cat());//DESIRE COMPILE ERROR
freezer.add(new IceCream());//DESIRE OK
freezer.add(new MyBrother());///DESIRE COMPILE ERROR
freezer.add(new Banana());//DESIRE COMPILER ERROR
freezer.add(new Marbles());//DESIRE COMPILER ERROR
}
}//end

一个想法是创建一个包罗万象的接口(interface),然后传递它:

interface WillFitInMiniFoodFreezer extends Edible, SmallerThanABeachball, Freezeable{}
class MiniFoodFreezer extends StorageChest<WillFitInMiniFoodFreezer>{
}

...但是,如果 Edible、SmallerThanABeachball 和 Freezeable 都来自第 3 方库,并且其他第三方库引用这些类型,其中一些具有满足 WillFitInMiniFoodFreezer 标准但没有明确要求的接口(interface)实现,该怎么办实现 WillFitInMiniFoodFreezer?

最佳答案

这里的问题是 Freezeable & Edible & SmallerThanABeachball本身不是类型 - 符号 ( & ) 只能在声明类型参数时用于定义多个上限,例如 <T extends Freezeable & Edible & SmallerThanABeachball> .此语言限制在此处进一步讨论:How to reference a generic return type with multiple bounds

一种解决方法是结合使用组合和通用 add方法:

class Freezer extends StoreageChest<Freezeable> { }

class MiniFoodFreezer {

private final Freezer freezer = new Freezer();

public <T extends Freezeable & Edible & SmallerThanABeachball> void add(
final T toStore
) {
freezer.add(toStore);
}
}

缺点是 MiniFoodFreezer不再 StoreageChest任何东西,所以你失去了继承的任何直接好处。但是,您可以根据需要公开相同对象的不同类型的 View 。例如,假设 StoreageChest<T>工具 Iterable<T> :

class MiniFoodFreezer {

private final Freezer freezer = new Freezer();

public <T extends Freezeable & Edible & SmallerThanABeachball> void add(
final T toStore
) {
freezer.add(toStore);
}

public Iterable<Freezeable> asFreezables() {
return freezer;
}

public Iterable<Edible> asEdibles() {
// this is okay because add must take an Edible and Iterable is read-only
@SuppressWarnings("unchecked")
final Iterable<Edible> edibles = (Iterable<Edible>)(Iterable<?>)freezer;
return edibles;
}

public Iterable<SmallerThanABeachball> asSmallerThanBeachballs() {
// same reasoning as above
@SuppressWarnings("unchecked")
final Iterable<SmallerThanABeachball> smallerThanBeachballs =
(Iterable<SmallerThanABeachball>)(Iterable<?>)freezer;
return smallerThanBeachballs;
}
}

然后我们可以做:

final MiniFoodFreezer miniFoodFreezer = new MiniFoodFreezer();
miniFoodFreezer.add(new IceCream());
miniFoodFreezer.add(new SnoCone());
miniFoodFreezer.add(new Slushy());

for (final Freezeable freezable : miniFoodFreezer.asFreezables()) {
// do freezable stuff
}

for (final Edible edible : miniFoodFreezer.asEdibles()) {
// do edible stuff
}

for (
final SmallerThanABeachball smallerThanABeachBall :
miniFoodFreezer.asSmallerThanBeachballs()
) {
// do smaller-than-a-beach-ball stuff
}

关于java - 扩展泛型类时如何传递多个泛型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20716651/

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