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

时间:2016-07-06 14:51:09

标签: java

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

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

如何将我自己接受方法的课程作为上述参数?

4 个答案:

答案 0 :(得分:1)

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

KeyListener是interface,需要实现这3种方法。

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

public interface SomeInterface {
    public void foo();
    public int bar(int x);
}

然后你可以匿名使用它(比如在你的例子中),或者在类中实现它:

public class MyClass implements SomeInterface {
    // ...
}

答案 1 :(得分:1)

new KeyListener() { ... }实际上创建了一个实现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
      }
    });
  }
}

如果要为密钥监听器提供构造函数,则需要明确定义一个类,如anonymous classes can't have custom constructors。这意味着你必须做这样的事情(注意:伪代码):

class Outer {
  void initUI() {
    JFrame.addKeyListener( new InnerKeyListener( myParam ) );
  }

  class InnerKeyListener implements KeyListener {
    InnerKeyListener( Param p ) {
    }

    ...
  }
}

当然你也可以把内部类放到一个separe文件中,或者把它变成一个静态的内部类。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

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

    abstract ReturnType name(Parameter p);

并且在调用时的行为与方法完全相同。完整的例子:

    //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);

你需要做的是这样的事情:

    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