Java 如何使方法成为构造函数的参数

Java 如何使方法成为构造函数的参数,java,Java,在用Java制作一个小游戏时,我偶然发现了keyListener类,它在实例化时要求使用三种方法(keyTyped、keyPressed和KeyRelease),如下所示: JFrame.addKeyListener(new KeyListener(){ public void keyTyped(KeyEvent evnt) { //blah } public void keyPressed(KeyEvent evnt) { //blah }

在用Java制作一个小游戏时,我偶然发现了keyListener类,它在实例化时要求使用三种方法(keyTyped、keyPressed和KeyRelease),如下所示:

JFrame.addKeyListener(new KeyListener(){
    public void keyTyped(KeyEvent evnt) {
    //blah
    }
    public void keyPressed(KeyEvent evnt) {
    //blah
    }
    public void keyReleased(KeyEvent evnt) {
    //blah
    }
});

我怎样才能得到一个我自己制作的类,像上面那样接受方法作为参数?

它不接受方法作为参数。您正在声明一个匿名类,并将其作为参数传递给addKeyListener方法。

从技术上讲,这些方法在这里不是参数。唯一的参数是KeyListener的一个匿名实例

KeyListener是一个
接口
,需要实现这3种方法

如果要定义自己的接口,它看起来类似于类:

public interface SomeInterface {
    public void foo();
    public int bar(int x);
}
然后,您可以匿名使用它(如示例中所示),或者通过在类中实现它:

public class MyClass implements SomeInterface {
    // ...
}
newKeyListener(){…}
实际上创建了一个实现
KeyListener
的匿名内部类。因此,它可以访问创建它的类的任何可见字段,以及调用构造函数的方法中的任何局部最终变量

例如:

class Outer {
  int x;

  void initUI( final int z) {
    final int y = 0;        
    int nope = 1; //you can't access this since it is neither final nor a field like x

    JFrame.addKeyListener( new KeyListener() {
      public void keyTyped(KeyEvent evnt) {
        System.out.println( x + y + z ); //you can access all of them
      }
    });
  }
}
如果要为密钥侦听器提供构造函数,则需要显式定义一个类,如下所示。这意味着您必须这样做(注意:伪代码):


当然,您也可以将内部类放入一个separe文件中,或者将其设置为静态内部类。

我知道回答我自己的问题很奇怪,但是

我想出来了。您必须使类抽象,并且可以声明抽象方法以使方法“参数”,使其行为类似于KeyListener声明。抽象方法声明如下:

    abstract ReturnType name(Parameter p);
    Foo f = new Foo(4) {
        @Override
        void doStuff() {
            System.out.println("Hi guys! I am an abstract method!");
        }
        @Override
        void whatDoIDoWith(int thisNumber) {
            blah += thisNumber;
            System.out.println(blah);
        }
     }; //Always remember this semicolon!
调用时的行为与方法完全相同。举一个完整的例子:

    //The abstract keyword enables abstract methods to work with this class.
    abstract class Foo {
        //Just a random variable and a constructor to initialize it
        int blah;
        public Foo(int blah) {
            this.blah = blah;
        }
        //An abstract method 
        abstract void doStuff();
        //Example with a parameter
        abstract void whatDoIDoWith(int thisNumber);
        //A normal method that will call these methods.
        public void doThings() {
            //Call our abstract method.
            doStuff();
            //Call whatDoIDoWith() and give it the parameter 5, because, well... 5!
            whatDoIDoWith(5);
        }
    }
当您尝试像普通类一样实例化抽象类时,Java会崩溃

    Foo f = new Foo(4);
你需要做的事情如下:

    abstract ReturnType name(Parameter p);
    Foo f = new Foo(4) {
        @Override
        void doStuff() {
            System.out.println("Hi guys! I am an abstract method!");
        }
        @Override
        void whatDoIDoWith(int thisNumber) {
            blah += thisNumber;
            System.out.println(blah);
        }
     }; //Always remember this semicolon!
注意,这里需要包括所有的抽象方法,而不仅仅是其中的一些。现在,让我们试试这个:

    public class Main {
        public static void main(String[] args) {
            //Instance foo.
            Foo f = new Foo(4) {
                @Override
                void doStuff() {
                    System.out.println("Hi guys! I am an abstract method!");
                }
                @Override
                void whatDoIDoWith(int thisNumber) {
                    blah += thisNumber;
                    System.out.println(blah);
                }
            };
            //Call our method where we called our two abstract methods.
            foo.doThings();
        }
    }
这会将以下内容打印到控制台:

    Hi guys! I am an abstract method!
    9
看看这个,,