我正在学习Java 8中的Lambda表达式和方法引用,并且看到我们可以通过使用'super'来引用方法的超类版本,
super :: name
但是当我这样做时,它不起作用。这是示例代码:
interface MyInterface {
int someFunc(int x);
}
class A {
static int Func(int y) {
// return (int) (Math.random() * y);
return y;
}
}
class B extends A {
static int Func(int y) {
// return (int) (Math.random() * y);
return y + 1;
}
}
public class Test {
public static void main(String[] args) {
System.out.print("Enter a number: ");
java.util.Scanner scanner = new java.util.Scanner(System.in);
int result = funcOp(B::Func, scanner.nextInt()); // <-This works.
//int result = funcOp(B.super::Func, scanner.nextInt()); <--This is not working.
//Getting: error: not an enclosing class: B
int result = funcOp(B.super::Func, scanner.nextInt());
^
scanner.close();
System.out.println(result);
}
static int funcOp(MyInterface mI, int num) {
return mI.someFunc(num);
}
}
请告诉我,我实现此代码有误吗?据我了解,由于方法“ X”满足方法“ Y”的条件和行为,并且可以潜在地替代方法,因此我们可以通过方法“ X”作为参考,以实现功能接口方法“ Y”的实现。在这种情况下为“ Y”。
这不对吗,我是否以错误的方式获得了方法引用?
感谢您对此的投入:)
答案 0 :(得分:5)
来自the JLS:
super.Identifier形式是指当前对象的名为Identifier的字段,但当前对象被视为当前类的超类的实例。
[...]
使用关键字super的表单仅在实例方法,实例初始化器或类的构造函数或类的实例变量的初始化器中有效。 如果它们出现在其他任何地方,则会发生编译时错误。
您正在从类类型中调用super
,从而导致编译错误。
许多人在评论中建议您只需在A::Func
方法中传递funcOp
。
请注意,您也将无法从super
方法中调用Func
,因为它是static
方法,因此它并不与类实例相关。
根据OP的评论进行编辑
您可以从实例方法中使用super
关键字(因此,如果您删除了static的话),它看起来像这样:
class B extends A {
int Func(int y) {
// e.g:
if (y > 10) {
return super.Func(y); // call Func from the parent class
}
return y + 1;
}
}
答案 1 :(得分:0)
super 和 this 关键字是引用某个对象的参考变量。换句话说,它属于该类的实例。
如果您要寻找替代方法而不是 A :: Func
,则可以执行以下操作class B extends A {
static int Func(int y) {
// return (int) (Math.random() * y);
return y + 1;
}
public int getSuperFunc(int y)
{
//call A class Func(int y)
return super.Func(y);
}
}
在Test类的主方法中
System.out.print("Enter a number: ");
java.util.Scanner scanner = new java.util.Scanner(System.in);
//int result = funcOp(B::Func, scanner.nextInt()); // <-This works.
B b=new B();
int result1 = funcOp(b::getSuperFunc, scanner.nextInt()); // <-This works.
scanner.close();
System.out.println(result1);
输出
Enter a number: 1
1