Как обратиться к версии суперкласса метода, используя super :: methodName в выражении lamda - PullRequest
0 голосов
/ 30 октября 2018

Я изучаю лямбда-выражения и ссылки на методы в Java 8 и вижу, что мы можем ссылаться на версию метода суперкласса, используя 'super', как:

супер :: имя

Но когда я это делаю, это не работает. Вот пример кода:

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» в этой ситуации.

Разве это не правильно, я неправильно получил ссылки на методы?

Спасибо за ваш вклад в это :)

Ответы [ 2 ]

0 голосов
/ 30 октября 2018

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
0 голосов
/ 30 октября 2018

С JLS :

Форма super.Identifier ссылается на поле с именем Identifier текущего объекта, но текущий объект рассматривается как экземпляр суперкласса текущего класса.

[...]

Формы , использующие ключевое слово super, действительны только в методе экземпляра , инициализаторе экземпляра или конструкторе класса или в инициализаторе переменной экземпляра класса. Если они появляются где-то еще, возникает ошибка времени компиляции .

Вы вызываете super из типа класса, таким образом, ошибка компиляции.

Как многие предлагают в комментарии, вы должны просто передать A::Func в методе funcOp.


Обратите внимание, что вы также не сможете вызывать super из вашего Func метода, так как это метод static, поэтому он не привязан к экземпляру класса.


Редактировать следующий комментарий ОП

Вы можете использовать ключевое слово 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;
    }
}
...