Search code examples
javacallbackclosuresoverriding

Why can't it be overridden, if possible?


I'm learning Java, I met an example of Closure:

public class Callbacks {

    public static void main(String[] args) {
        Callee1 c1 = new Callee1();
        Callee2 c2 = new Callee2();
        MyIncrement.f(c2);
        Caller caller1 = new Caller(c1);
        Caller caller2 = new Caller(c2.getcallbackReference());
        caller1.go();
        caller1.go();
        caller2.go();
        caller2.go();

    }

}

interface Incrementable {
    void increment();
}

class Callee1 implements Incrementable {
    private int i = 0;

    @Override
    public void increment() {
        i++;
        print(i);
    }
}

class MyIncrement {
    public void increment() {
        System.out.println("another operation");
    }

    public static void f(MyIncrement m) {
        m.increment();
    }
}


class Callee2 extends MyIncrement {
    private int i = 0;
    
    
    public void increment() {
        super.increment();
        i++;
        print(i);
    }

    private class Closure implements Incrementable {
        
        @Override
        public void increment() {
            Callee2.this.increment();
        }
    }

    Incrementable getcallbackReference() {
        return new Closure();
    }
}

class Caller {
    Incrementable callbackRegerence;

    Caller(Incrementable cbh) {
        callbackRegerence = cbh;
    }

    void go() {
        callbackRegerence.increment();
    }
}

Comment from the author of the example :

When Mylncrement is inherited into Callee2, increment( ) can’t be overridden for use by Incrementable, so you’re forced to provide a separate implementation using an inner class.

My question is: What? Why can't we? We can override it in the Callee2 class or did I misunderstand the author? Please explain what he wanted to say with this comment.


Solution

  • You need to have a type of Incrementable as a Caller argument. You can change this to have the same.

    old

    class Callee2 extends MyIncrement {
        private int i = 0;
        
        
        public void increment() {
            super.increment();
            i++;
            print(i);
        }
    
        private class Closure implements Incrementable {
            
            @Override
            public void increment() {
                Callee2.this.increment();
            }
        }
    
        Incrementable getcallbackReference() {
            return new Closure();
        }
    }
    

    New:

    class Callee2 extends MyIncrement implements Incrementable {
        private int i = 0;
    
    
        public void increment() {
            super.increment();
            i++;
            System.out.println(i);
        }
    }