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

编程入门 行业动态 更新时间:2024-10-26 12:31:58
本文介绍了扩展泛型类时如何传递多个泛型参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

下面的代码不会编译,但我希望创建一些类似的功能来编译:

The following will not compile but I wish to create something of similar functionality which will compile:

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

一个想法是创建一个全面的接口,然后通过

One thought was to create an all-encompassing interface and then pass that:

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

...但是如果Edible,SmallerThanABeachball和Freezeable都来自第三方库和其他第三方库引用这些类型,其中一些必须满足WillFitInMiniFoodFreezer条件的接口实现,但没有明确实现WillFitInMiniFoodFreezer?

...however what if Edible, SmallerThanABeachball, and Freezeable are all from a 3rd party library and other third-party libraries refer to these types, some of which have the interface implementations necessary meet the criteria for WillFitInMiniFoodFreezer but do not explicitly implement WillFitInMiniFoodFreezer?

推荐答案

这里的问题是 Freezeable&食用& SmallerThanABeachball 本身不是一种类型 - 例如,在声明类型参数时,&符号(& )只能用于定义多个上限,例如< T扩展了Freezeable&食用& SmallerThanABeachball> 。此语言限制在此处进一步讨论:如何引用具有多个边界的泛型返回类型

The issue here is that Freezeable & Edible & SmallerThanABeachball is not itself a type - the ampersand (&) can only be used to define multiple upper bounds when declaring a type parameter, for example <T extends Freezeable & Edible & SmallerThanABeachball>. This language limitation is further discussed here: How to reference a generic return type with multiple bounds

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

One workaround is to use a combination of composition and a generic add method:

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 ,所以您失去了继承的直接好处。但是,您可以根据需要公开不同类型的视图。例如,假设 StoreageChest< T> implements Iterable< T> :

The downside being that MiniFoodFreezer no longer is-a StoreageChest of anything, so you lose any direct benefits of inheritance. However, you can expose differently typed views of the same objects as needed. For example, assume StoreageChest<T> implements 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 }

更多推荐

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

本文发布于:2023-11-09 10:32:06,感谢您对本站的认可!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:多个   参数   泛型类时

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!