Передача объекта интерфейса в конструктор JAVA

public class CalculatorWithAutoAggregationSetup1  implements ICalculator {
    ICalculator ic;
    CalculatorWithOperator cwo;
    public CalculatorWithAutoAggregationSetup1(ICalculator ic) {
        this.ic = ic;

    }
    private int counter;
    private long memory;

    public CalculatorWithAutoAggregationSetup1() {

    }


    public double divide(double a, double b) {
        counter++;
        return ic.divide(a,b);
    }

    public double multiplication(double a, double b) {
        counter++;
        return a * b;
    }

    public double plus(double a, double b) {
        counter++;
        return a + b;
    }

    public double minus(double a, double b) {
        counter++;
        return a - b;
    }

    public double square(double a, int b) {
        double square = 1;
        for (int i = 0; i < b; i++) {
            square *= a;
        }
        counter++;
        return square;
    }

    public double module(double a) {
        if (a < 0) {
            a = -(a);
        }
        counter++;
        return a;
    }

    public double root(double a) {
        double x;
        if (a<0) {
            a = -(a);
        }
        double half = a / 2;
        do {
            x = half;
            half = (x + (a / x)) / 2;
        } while ((x - half) != 0);
        counter++;
        return half;
    }
    public long getCounter() {
        return  counter;
    }

Не могу понять, если мы передаём объект типа ICalculator, то в main мы должны будем его создать(как я понимаю), но объект интерфейса нельзя создать без реализации его методов. Плюс надо делегировать методы без собственной математике, но как я понимаю делегировать без другого класса я не могу, и интерфейсом в том числе(т.к. он без реализации). Вопрос в том, что я должен передать в конструктор, точнее каким образом (ICalculator обязательно передать), чтобы я мог и делегировать методы и мог запустить main.


Ответы (1 шт):

Автор решения: стасевич

слышал что-нибудь про полиморфизм? один интерфейс - множество реализаций?

если кратко, интерфейс - это контракт, гарантирующий, что у нас будет определённое поведение, т.е. мы на 100% уверены, что в любом классе реализующем интерфейс будет нужный метод.

interface Speakable {
    void speak();
}

и создадим три класса и у каждого будет свой метод speak

class Cat implements Speakable {
    @Override
    public void speak() {
        System.out.println("мяу");
    }
}

class Dog implements Speakable {
    @Override
    public void speak() {
        System.out.println("гав");
    }
}

class Developer implements Speakable {
    @Override
    public void speak() {
        System.out.println("учу джаву");
    }
}  

и в мейне можем создать обьект через интерфейс

Speakable speakable = new Developer();
Speakable speakableCat = new Cat();
Speakable speakableDog = new Dog();

мы можем создать метод принимающий любой объект Speakable, т.к. мы знаем что у него будет метод speak, и в будущем сможем создавать и добавлять любые реализации не переписывая текущий код.

void test(Speakable speakable) {
        speakable.speak();
    }

Коллекции тоже через интерфейс создаются.

public static void main(String[] args) {
        //лист обьектов реализующих контракт Speakable
        List<Speakable> list = new ArrayList<>();
        list.add(new Cat()); 
        list.add(new Dog());  
        list.add(new Developer());

        for (Speakable speakable : list) {
            speakable.speak();
        }
    }  

вывод

мяу
гав
учу джаву  

если не создавать обьекты, то передать в метод анонимный класс либо лямбду . это должен быть функциональный интерфейс с одним абстрактным методом.

public class Test {

    static void test(Speakable speakable) {
        speakable.speak();
    }

    public static void main(String[] args) {
        test(new Speakable() {
            @Override
            public void speak() {
                System.out.println("через анонимный класс");
            }
        });

        test(() -> System.out.println("через лямбду"));

    }
}
→ Ссылка