相关疑难解决方法(0)

为什么接口必须用Java声明?

有时我们有几个类具有相同签名的某些方法,但是它们与声明的Java接口不对应.例如,两者JTextFieldJButton(在其他几个中 javax.swing.*)都有一种方法

public void addActionListener(ActionListener l)
Run Code Online (Sandbox Code Playgroud)

现在,假设我希望对具有该方法的对象执行某些操作; 那么,我想要一个界面(或者自己定义它),例如

  public interface CanAddActionListener {
      public void addActionListener(ActionListener l);
  }
Run Code Online (Sandbox Code Playgroud)

所以我可以写:

  public void myMethod(CanAddActionListener aaa, ActionListener li) {
         aaa.addActionListener(li);
         ....
Run Code Online (Sandbox Code Playgroud)

但是,遗憾的是,我不能:

     JButton button;
     ActionListener li;
     ...
     this.myMethod((CanAddActionListener)button,li);
Run Code Online (Sandbox Code Playgroud)

这个演员是非法的.编译器知道JButton 不是 a CanAddActionListener,因为类没有声明实现该接口...... 但是它"实际"实现了它.

这有时会带来不便 - 而Java本身已经修改了几个核心类来实现由旧方法构成的新接口(String implements CharSequence例如).

我的问题是:为什么会这样?我理解声明一个类实现接口的实用程序.但无论如何,看看我的例子,为什么编译器不能推断出类JButton"满足"接口声明(查看它内部)并接受转换?这是编译器效率的问题还是存在更多基本问题?

我对答案的总结:这是一个Java可以允许一些"结构类型"(一种鸭子打字 - 但在编译时检查)的情况.它没有.除了一些(对我来说不清楚)性能和实现困难之外,还有一个更为基本的概念:在Java中,接口的声明(以及一般来说,所有内容)并不仅仅是结构性的(具有方法)这些签名)但语义:这些方法应该实现一些特定的行为/意图.因此,一个在结构上满足某些接口的类(即,它具有所需签名的方法)并不一定在语义上满足它(一个极端的例子:回想一下"标记接口",它甚至没有方法!).因此,Java可以断言一个类实现了一个接口,因为(并且只是因为)已经显式声明了它.其他语言(Go,Scala)有其他语言.

java duck-typing static-typing interface structural-typing

8
推荐指数
2
解决办法
748
查看次数