java - 如何正确使用多个边界?
问题描述
我试图创建一个实例化一个名为“MultipleBoundsClass”的通用类,该类具有多个边界 - 一个名为“OrderedPair”的类和一个名为“Pair”的接口(Ordered Pair 实现)。
我试过删除接口边界,让我编译。但我不知道为什么会这样,以及 Id 如何在包含接口边界的情况下成功实现它。
public interface Pair<K, V>
{
public K getKey();
public V getValue();
}
public class OrderedPair<K, V> implements Pair
{
private K key;
private V value;
public OrderedPair(K key, V value)
{
this.key = key;
this.value = value;
}
public K getKey()
{
return key;
}
public V getValue()
{
return value;
}
}
class OrderedPair {}
interface Pair {}
public class MultipleBounds<T extends OrderedPair & Pair>
{
private T t;
public MultipleBounds(T t)
{
this.t = t;
}
public T getPair()
{
return t;
}
}
public static void main(String[] args)
{
OrderedPair<String, Integer> p1 = new OrderedPair<>("even", 8);
MultipleBounds<OrderedPair> myPair = new MultipleBounds<OrderedPair>(p1);
}
我收到错误“类型参数 OrderedPair 不在类型变量 T 的范围内”。有界类型将泛型参数的参数限制为您定义的类及其子类,那么当接口被包含为当前边界时,为什么类型 OrderedPair 不在其自身范围内?
解决方案
我想提供一个示例,说明您如何使用多个边界。这很奇怪,但可能有助于理解事情。
假设我们有一个Container
,并且我们能够输入put
一些东西。
abstract class Container {
private Object content;
public void put(Object object) { this.content = object; }
public Object get() { return content; }
}
然后,有一些接口可以为这些容器定义一些属性。它们可能是Rollable
和/或Inflammable
。
interface Rollable { void roll(); /* rolls somehow */ }
interface Inflammable { void burnItself(); /* burns somehow */ }
然后,我们定义具体Container
的类: a CardboardBox
、 a GiftBox
、 aMetalBarrel
和 a WoodBarrel
,并根据它们的属性实现接口:
class CardboardBox extends Container implements Inflammable {
@Override
public void burnItself() { /* omit implementation */ }
}
class GiftBox extends Container implements Rollable, Inflammable {
@Override
public void burnItself() { /* omit implementation */ }
@Override
public void roll() { /* omit implementation */ }
}
class MetalBarrel extends Container implements Rollable {
@Override
public void roll() { /* omit implementation */ }
}
class WoodBarrel extends Container implements Rollable, Inflammable {
@Override
public void burnItself() { /* omit implementation */ }
@Override
public void roll() { /* omit implementation */ }
}
现在,真正的离奇。假设你想创建一个Stock
,所有东西都必须在的地方Rollable
。和Inflammable
。因为你想把你所有的容器都卷进去,并且能够烧掉其中一个。你定义一个Stock
:
class Stock <T extends Container & Rollable & Inflammable> {
private List<T> containers;
void addContainer(T container) { containers.add(container); }
void rollAllContainers() { containers.forEach(Rollable::roll); }
void burnContainer(int index) { containers.get(index).burnItself(); }
}
然后您就可以创建其中之一。您不受Container
类型的束缚;只是它的属性——因为它们是由接口定义的。
public static void main(String[] args) {
Stock<GiftBox> giftBoxStock = new Stock<>();
GiftBox giftBox = new GiftBox();
giftBox.put("a gift");
GiftBox giftBox1 = new GiftBox();
giftBox1.put("another gift");
giftBoxStock.addContainer(giftBox);
giftBoxStock.addContainer(giftBox1);
giftBoxStock.rollAllContainers();
giftBoxStock.burnContainer(0);
Stock<WoodBarrel> woodBarrelStock = new Stock<>();
WoodBarrel woodBarrel = new WoodBarrel();
woodBarrel.put("wine");
WoodBarrel woodBarrel1 = new WoodBarrel();
woodBarrel1.put("gas");
woodBarrelStock.addContainer(woodBarrel);
woodBarrelStock.addContainer(woodBarrel1);
woodBarrelStock.rollAllContainers();
woodBarrelStock.burnContainer(1);
}
推荐阅读
- numpy - 在 x 和 y 值上使用不同大小的数组喂养 pyplot
- sql-server - 如何在 asp.net 核心中工作并将新表添加到数据库第一个模型?
- javascript - 访问 Promise.then() 中的拖放对象?
- python - 每次代码运行时如何保存数据并附加到它
- ios - 将数据从 UIViewController 传递到 UITabBarController 始终为零
- flutter - 是否可以在飞镖中动态设置方法的返回类型
- python - 在 Android Studio 中使用 Chaquopy 将值插入到 python 文件中
- vba - 从抓取的表格中提取单元格值的最有效方法
- c# - 是否可以在 HwndHost 中托管 WPF 页面?
- chart.js - 如何在工具提示回调afterBody中将逗号分隔的字符串分成新行?