2011-10-01 36 views
4

我在C#中有一个简单的Screen类,它有一堆事件(与相应的委托),如FadeOutEventJava相当于C#的委托/事件:动态更改事件调用代码

我想将我的库移植到Java,并且我发现事件/委托的机制真的很乱。具体来说,我不能轻易写这样的代码:

if (someVar == someVal) { 
    this.FadeOutComplete +=() => { 
    this.ShowScreen(new SomeScreen()); 
    }; 
} else { 
    this.FadeOutComplete +=() => { 
    this.ShowScreen(new SomeOtherScreen()); 
    }; 
} 

为了你纯Java的家伙,从本质上讲,我哀的是无法重新分配事件处理方法在当前类别的动态,而不创建新类;似乎如果我使用接口,当前类必须执行接口,并且我不能更改稍后调用的代码。

在C#中,这是常见的,你有一些代码:

  • 在构造函数/早,分配一些事件处理代码,事件执行期间
  • 后,取出该代码完全
  • 通常情况下,即原来的处理程序切换到不同的处理程序代码

策略模式可以解决这个问题(并执行),尽管我NE编辑额外的类和接口来完成它;在C#中,它只是一个有趣的事件/委托,我完成了。

有没有办法做到这一点,没有内部/匿名类?

编辑:我刚才看到this SO question,这可能会有所帮助。

+0

只需搜索“[java]战略模式”,就会发现很多很多的例子。 –

+1

@HovercraftFullOfEels我做到了。他们大多需要很多额外的类(甚至匿名类),我真的不喜欢。作为一名C#开发人员,这是微不足道的,不需要类。当然,我可以用私人/内部课程来完成,但为什么我必须这样做? – ashes999

+1

@ ashes999 Umn如何在没有lambda的情况下实现你的事件 - 这与c#中的匿名内部类(实际上与它的约束和所有内容几乎完全相同)基本相同?除了Java笨拙的语法之外,最大的区别是你需要一个接口来定义委托/事件。而且没有办法解决这个问题,因为函数不是Java中的头等对象。 – Voo

回答

12

大部分时间里,它的完成反过来:

this.addActionListener(new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     if (someVar == someVal) { 
      showSomeScreen(); 
     } 
     else { 
      showSomeOtherScreen(); 
     } 
    } 
}); 

但是你可以通过委托给另外两个对象做一些类似的C#代码的东西:提出

private Runnable delegate; 

// ... 
this.addActionListener(new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     delegate.run(); 
    } 
}); 

// ... 
if (someVar == someVal) { 
    this.delegate = new Runnable() { 
     @Override 
     public void run() { 
      showSomeScreen(); 
     } 
    }; 
} 
else { 
    this.delegate = new Runnable() { 
     @Override 
     public void run() { 
      showSomeOtherScreen(); 
     } 
    }; 
} 

代表很久以前微软公司为Java提供,并被Sun拒绝。我不记得当时是否存在匿名内部类,或者他们是否被选为替代方案。

+0

+1这是我也得出的结论。也许我们仍然可以做得更好,但是我担心这样做会很好。 – ashes999

+0

另外,我的例子有点肤浅,我所得到的是经常添加/删除/更改代表。这在Java中似乎很难。 – ashes999