Java泛型(1/N)类型
我想声明泛型类型是类型的子集之一,但我不确定如何声明。以下是我的情况的简化版本: 模块与事件通信。有不同类型的事件。模块可以使用不同的方法使用不同的事件类型Java泛型(1/N)类型,java,generics,types,Java,Generics,Types,我想声明泛型类型是类型的子集之一,但我不确定如何声明。以下是我的情况的简化版本: 模块与事件通信。有不同类型的事件。模块可以使用不同的方法使用不同的事件类型 class EventProducerA implements Producer<EventTypeA>{ @Override public EventTypeA produce_event(){ return new EventTypeA(...); } } class EventPr
class EventProducerA implements Producer<EventTypeA>{
@Override
public EventTypeA produce_event(){
return new EventTypeA(...);
}
}
class EventProducerB implements Producer<EventTypeB>{
@Override
public EventTypeB produce_event(){
return new EventTypeB(...);
}
}
class EventConsumer{
public void feed_event(EventTypeA ev){
...
}
public void feed_event(EventTypeB ev){
...
}
}
类EventProducerA实现Producer{
@凌驾
公共事件类型A生成_事件(){
返回新的EventTypeA(…);
}
}
类EventProducerB实现Producer{
@凌驾
公共事件类型B生成_事件(){
返回新的EventTypeB(…);
}
}
类事件消费者{
公共无效馈送事件(EventTypeA ev){
...
}
公共无效源事件(EventTypeB ev){
...
}
}
现在,我有了一个主类,我在其中链接这些模块。我想要代码:
Producer<EventTypeA OR EventType B> producer = some_flag?new EventProducerA():new EventProducerB();
Consumer consumer = new EventConsumer()
consumer.feed_event(producer.produce_event());
Producer-Producer=some_标志?new EventProducerA():new EventProducerB();
消费者消费者=新事件消费者()
consumer.feed_事件(producer.product_事件());
如果生产者生成了消费者未处理的某些EventTypeC,则会导致编译错误
但不幸的是,Java中没有泛型类型的OR选项
那最好的办法是什么呢?我是否被迫使用丑陋的强制转换解决方案?即使尝试过,也不会有令人讨厌的强制转换解决方案起作用,因为如果
EventConsumer
对不同的事件类型有不同的重载,那么您必须在编译时知道在哪个代码路径中选择了哪个重载。做一件尴尬但直截了当的事:
if (some_flag) {
Producer<EventTypeA> producer = new EventProducerA();
Consumer consumer = new EventConsumer();
consumer.feed_event(producer.produce_event());
} else {
Producer<EventTypeB> producer = new EventProducerB();
Consumer consumer = new EventConsumer();
consumer.feed_event(producer.produce_event());
}
if(某些_标志){
Producer-producera=新事件producera();
消费者=新事件消费者();
consumer.feed_事件(producer.product_事件());
}否则{
Producer-producerb=新事件producerb();
消费者=新事件消费者();
consumer.feed_事件(producer.product_事件());
}
不要想入非非。即使您尝试过,也不会有糟糕的强制转换解决方案奏效,因为如果
EventConsumer
对不同的事件类型有不同的重载,那么您必须在编译时知道在哪个代码路径中选择了哪个重载。做一件尴尬但直截了当的事:
if (some_flag) {
Producer<EventTypeA> producer = new EventProducerA();
Consumer consumer = new EventConsumer();
consumer.feed_event(producer.produce_event());
} else {
Producer<EventTypeB> producer = new EventProducerB();
Consumer consumer = new EventConsumer();
consumer.feed_event(producer.produce_event());
}
if(某些_标志){
Producer-producera=新事件producera();
消费者=新事件消费者();
consumer.feed_事件(producer.product_事件());
}否则{
Producer-producerb=新事件producerb();
消费者=新事件消费者();
consumer.feed_事件(producer.product_事件());
}
不要装腔作势。不幸的是,你所要求的无法实现。如果您仔细考虑一下,就会删除关于
product\u event
生成的类型的静态信息,从而防止编译器知道应该使用什么样的feed\u event
重载
作为替代解决方案,您可以简单地添加一些样板代码:
if(some_flag)
{
EventProducerA producer = new EventProducerA();
Consumer consumer = new EventConsumer();
consumer.feed_event(producer.produce_event());
}
else
{
EventProducerA producer = new EventProducerA();
Consumer consumer = new EventConsumer();
consumer.feed_event(producer.produce_event());
}
如果您不喜欢此解决方案,则需要找到一种获得双重分派的方法
interface IProducer
{
void consume_event(Consumer consumer);
}
abstract class Producer<T> : IProducer
{
}
class EventProducerA implements Producer<EventTypeA>{
@Override
public EventTypeA produce_event(){
return new EventTypeA(...);
}
@Override void consume(Consumer consumer)
{
consumer.feed_event(produce_event());
}
}
class EventConsumer{
public void feed_event(IProducer p)
{
p.consume(this);
}
public void feed_event(EventTypeA ev){
...
}
public void feed_event(EventTypeB ev){
...
}
}
接口IProducer
{
无效消费事件(消费者);
}
抽象类生产者:IProducer
{
}
类EventProducerA实现Producer{
@凌驾
公共事件类型A生成_事件(){
返回新的EventTypeA(…);
}
@覆盖无效消费(消费者)
{
consumer.feed_事件(product_event());
}
}
类事件消费者{
公共无效源事件(IProducer p)
{
p、 消耗(这个);
}
公共无效馈送事件(EventTypeA ev){
...
}
公共无效源事件(EventTypeB ev){
...
}
}
最后,您可能想看看如何使用函数式编程语言中的代数数据类型 不幸的是,你的要求无法实现。如果您仔细考虑一下,就会删除关于
product\u event
生成的类型的静态信息,从而防止编译器知道应该使用什么样的feed\u event
重载
作为替代解决方案,您可以简单地添加一些样板代码:
if(some_flag)
{
EventProducerA producer = new EventProducerA();
Consumer consumer = new EventConsumer();
consumer.feed_event(producer.produce_event());
}
else
{
EventProducerA producer = new EventProducerA();
Consumer consumer = new EventConsumer();
consumer.feed_event(producer.produce_event());
}
如果您不喜欢此解决方案,则需要找到一种获得双重分派的方法
interface IProducer
{
void consume_event(Consumer consumer);
}
abstract class Producer<T> : IProducer
{
}
class EventProducerA implements Producer<EventTypeA>{
@Override
public EventTypeA produce_event(){
return new EventTypeA(...);
}
@Override void consume(Consumer consumer)
{
consumer.feed_event(produce_event());
}
}
class EventConsumer{
public void feed_event(IProducer p)
{
p.consume(this);
}
public void feed_event(EventTypeA ev){
...
}
public void feed_event(EventTypeB ev){
...
}
}
接口IProducer
{
无效消费事件(消费者);
}
抽象类生产者:IProducer
{
}
类EventProducerA实现Producer{
@凌驾
公共事件类型A生成_事件(){
返回新的EventTypeA(…);
}
@覆盖无效消费(消费者)
{
consumer.feed_事件(product_event());
}
}
类事件消费者{
公共无效源事件(IProducer p)
{
p、 消耗(这个);
}
公共无效馈送事件(EventTypeA ev){
...
}
公共无效源事件(EventTypeB ev){
...
}
}
最后,您可能想看看如何使用函数式编程语言中的代数数据类型 总有办法
首先为两个事件创建公共接口
interface EventType {
void accept(EventConsumer consumer);
}
现在实施
class EventTypeA implements EventType {
@Override
public void accept(EventConsumer consumer) {
consumer.feed_event(this);
}
}
如何使用它?简单的
Producer<? extends EventType> producer = condition ? new EventProducerA() : new EventProducerB();
EventConsumer consumer = new EventConsumer();
EventType eventType= producer.produce_event();
eventType.accept(consumer);
Producer总有办法
首先为两个事件创建公共接口
interface EventType {
void accept(EventConsumer consumer);
}
现在实施
class EventTypeA implements EventType {
@Override
public void accept(EventConsumer consumer) {
consumer.feed_event(this);
}
}
如何使用它?简单的
Producer<? extends EventType> producer = condition ? new EventProducerA() : new EventProducerB();
EventConsumer consumer = new EventConsumer();
EventType eventType= producer.produce_event();
eventType.accept(consumer);
ProducerAh。这很好,除了可能的消费者群体不断扩大,而且事件类型相对较少之外。但是,我可以将accept方法放在所有事件的基类中,并让“`@覆盖public void accept(Consumer Consumer){Consumer.feed_event(this);}```。只是我现在需要某种方法来获取继承该方法的类的类型,我认为Java中也没有实现该方法@Peter仍然认为这不是一个问题,您可以传递consumer的基类,或者您甚至可以为此创建单独的接口(如果您使用的是Java8,那么您可以提供默认实现),这可能很麻烦,但您需要记住的是添加新的int