JetBrains Academy: Anonymous classes - Kamil-Jankowski/Learning-JAVA GitHub Wiki

JetBrains Academy: Anonymous classes

An anonymous class with a single method:

There is an interface:

interface SingleMethodInterface {
    void doSomething();
}

You should create an anonymous class that implements the given interface and assign the instance to the variable instance. The anonymous class must override the method doSomething() so that it outputs "The anonymous class does something" to the standard output.

SingleMethodInterface instance = new SingleMethodInterface(){
    @Override
    public void doSomething(){
        System.out.println("The anonymous class does something");
    }
};

An anonymous class with three methods:

There is an interface:

interface ThreeMethodsInterface {
    void do1();
    void do2();
    void do3();
}

You should create an anonymous class that implements the given interface and assign the instance to the variable instance. The anonymous class must override all methods. The overridden methods do1, do2, do3 must output strings "Implemented do1", "Implemented do2", "Implemented do3" respectively to the standard output. The case is important. Each output should be on a new line.

ThreeMethodsInterface instance = new ThreeMethodsInterface(){
    @Override
    public void do1(){
        System.out.println("Implemented do1");
    }

    @Override
    public void do2(){
        System.out.println("Implemented do2");
    }

    @Override
    public void do3(){
        System.out.println("Implemented do3");
    }
};

Calculator:

There is an abstract class Calculator:

abstract class Calculator {
    public abstract long sum(long val1, long val2);
    public abstract long subtraction(long val1, long val2);
}

You should create an anonymous class that extends the given class and assign the instance to the variable anonymousCalculator.

The anonymous class must override both abstract methods of the class. The method sum should return the sum of its arguments. The method subtraction should return the difference between the first and second argument.

Calculator anonymousCalculator = new Calculator(){
    @Override
    public long sum(long val1, long val2){
        return val1 + val2;
    }

    @Override
    public long subtraction(long val1, long val2){
        return val1 - val2;
    }
};

String reverser:

There is an interface StringReverser:

interface StringReverser {
    String reverse(String str);
}

You should create an anonymous class that implements the interface and assign the instance to the variable reverser. The anonymous class must override the method reverse of the interface. It should return the reversed input string.

StringReverser reverser = new StringReverser(){
    @Override
    public String reverse(String str){
        char[] strings = str.toCharArray();
        char[] reversed = new char[strings.length];
        for (int i = 0; i < strings.length; i++){
            reversed[strings.length-1 - i] = strings[i];
        }
        return String.valueOf(reversed);
    }
};

or:

StringReverser reverser = new StringReverser() {
    @Override
    public String reverse(String str) {
        return new StringBuilder(str).reverse().toString();
    }
};

A long process:

A program system manages a long process. To start the process you should invoke the static method startLongProcess that takes a callback. Here is the declaration of this method: public static void startLongProcess(Callback callback)

The Callback interface has three methods:

interface Callback {
    void onStarted();
    void onStopped(String cause);
    void onFinished(int code);
}

You should create an anonymous class that implements the Callback interface and pass the instance to the method startLongProcess as an argument. The method will call the passed callbacks at different stages of the process.

The anonymous class must override all methods of the Callback interface (otherwise the code won't be compiled).

  • The method onStarted must print the message "The process started" in the standard output.
  • The method onStopped takes a cause and print it to the standard output.
  • The method onFinished takes a code of the process completion. It should print "The process successfully finished" if the process is finished with the code 0, otherwise, the method should print the text "**The process is finished with error: **" plus the given code (for example, "The process is finished with error: 43"). All strings must be printed without quotes. Each message should be in a new line.

If the instance (callback) of your anonymous class is created correctly, after calling the following code:

callback.onStarted();
callback.onFinished(0);

you will get the following output:

The process started
The process successfully finished

Use the provided code template, do not copy the given class and the method.

startLongProcess(new Callback(){
    @Override
    public void onStarted(){
        System.out.println("The process started");
    }

    @Override
    public void onStopped(String cause){
        System.out.println(cause);
    }

    @Override
    public void onFinished(int code){
        System.out.println(code == 0 ? "The process successfully finished" : "The process is finished with error: " + code);
    }
});

Iterations:

There are two static methods:

1. static void performIterationsWithCallback(int numberOfIterations, LoopCallback callback) 2. static void startIterations(int numberOfIterations)

The first method takes a number of iterations for a loop and a callback that is called on each iteration. The second method takes a number of iterations, creates a callback and passes them to the first method.

The LoopCallback interface has a single method:

interface LoopCallback {
    void onNewIteration(int iteration);
}

You should implement the second method. It must create an instance of an anonymous class that implements LoopCallback and passes it to the first method. The overridden method onNewIteration should output the number of iteration to the standard output on a separate line.

static void performIterationsWithCallback(int numberOfIterations, LoopCallback callback) {
    for (int i = 0; i < numberOfIterations; i++) {
        callback.onNewIteration(i);
    }
}

static void startIterations(int numberOfIterations) {
    performIterationsWithCallback(numberOfIterations, new LoopCallback(){
        @Override
        public void onNewIteration(int number){
            System.out.println("Iteration: " + number);
        }
    });
}

Returning values from an anonymous class:

There is an interface Returner:

interface Returner {
    public String returnString();
    public int returnInt();
}

You should create an anonymous class that implements the interface and assign the instance to the variable returner. The anonymous class must override both methods of the interface. The method returnString should capture the string variable str from the context and return it, the second method should capture the integer variable number from the context and return it. These variables will be accessible during testing.

Returner returner = new Returner(){
    @Override
    public String returnString(){
        return str;
    }

    @Override
    public int returnInt(){
        return number;
    }
};

Returning from a method:

Java has a standard interface named java.lang.Runnable with the single method run(). The method has no arguments and returns nothing.

You should implement the given method createRunnable that takes two arguments: text and repeats. The method must return an instance of an anonymous class implementing java.lang.Runnable. The overridden method of the anonymous class should print the text to the standard output a specified number of times (repeats).

Use the provided code template, do not write the standard interface java.lang.Runnable.

public static Runnable createRunnable(String text, int repeats) {
    return new Runnable(){
        @Override
        public void run(){
            for (int i = 0; i < repeats; i++){
                System.out.println(text);
            }
        }
    };
}

Output names of the methods:

There is an abstract class:

abstract class SuperClass {    
    public static void method1() { }    
    public void method2() { }    
    public abstract void method3();
}

You should create an anonymous class that extends this abstract class and assign it to the instance variable. The anonymous class should override methods which can be overridden. Each overridden method must print its name to the standard output on a separate line without parentheses "()".

SuperClass instance = new SuperClass(){
    @Override    
    public void method2(){
        System.out.println("method2");
    }
    
    @Override
    public void method3(){
        System.out.println("method3");
    }
};