Metode default si statice in interfete

Meotde default

Incepand cu Java 8 este permisa adaugare unor implementari implicite pentru metodele definite incadrul unei interfete.

interface X{
    void m1();
    default void m2(){
        System.out.println("Do something! m1");
    }
}
 
interface Y extends X{
    default void m2(){
        System.out.println("Do something else! m1");
    }
}
 
public class TestDefaultInterface {
    public static void main(String[] args){
        X o1 = new X(){
            public void m1(){
                System.out.println("m1");
            }
        };
 
        o1.m1();
        o1.m2();
 
         Y o2 = new Y(){
            public void m1(){
                System.out.println("m1");
            }
        };
 
        o2.m1();
        o2.m2();
    }
}

Rezultatul executie codul de mai sus este:

m1
Do something! m1
m1
Do something else! m1

Dupa cum se observa in exemplul de mai sus o metoda implicita este prefixata de cuvantul cheie “default”. Obiectul o1 implementeaza metoda m1() dar nu implementeaza metoda m2(). In acest context implementarea implicita a metodei din interfata va fi executata.

O utilitate a metodelor default este aceea ca permite adugarea de metode noi intr-o interfata fara a fi nevoie sa modificam clasele care deja implementeaza acea interfata - astfel noile metode introduse in interfata for fi definite ca default cu o implementare implicita.

Mostenirea interfatelor cu implementare default

O interfata care mosteneste o interfata cu metode default poate pastra comportamentul metodelor default mostenite sau poate suprascrie acest comportament dupa cum se observa in interfata Y din exemplul aneterior.

Metode statice in interfete

Pe langa metode default o interfata poate contine de asemenea si metode statice. Aceste metode sunt utile in special in situatiile in care dorim sa oferim niste metode utilitare ce acompaniaza o interfata. Pana la Java 8 acest lucru nu era posibil si in general solutia utilizata era cea de a adauga o clasa nou utilitara ce continea metode statice utilitare. Un exemplu in acest sens este clasa java.utili.Collections ce ofera metode statice pentru manipularea colectiilor. Utilizand metode statice aceste clase utilitare pot fi eliminate.

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
 
/**
 *
 * @author evo
 */
public class TestDefaultSort {
 
    public static void main(String[] args){
        ArrayList<String> a = new ArrayList<>();
        a.add("xyz");
        a.add("abc");
        a.add("efg");
 
 
        //Before Java 8    
        Collections.sort(a, new Comparator<String>(){
 
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });
 
        System.out.println(a.toString());
 
        //In Java 8
        ArrayList<String> b = new ArrayList<>();
        b.add("xyz");
        b.add("abc");
        b.add("efg");
 
        b.sort(new Comparator<String>(){
 
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });
 
        System.out.println(a.toString());
 
    }   
}

Implementarea metodelor statice in interfete se face la fel ca si in cazul implementarii metodelor statice in cadrul claselor.

public class TestStaticmethodInterface {
   public static void main(String[] args){
       Instrument p = new Pian();
       p.play();
   } 
}
 
class Pian implements Instrument{
 
    @Override
    public void play() {
        System.out.println("Pianul canta nota "+Instrument.GenereazaNota(1));
    }
 
}
 
interface Instrument{
 
    void play();
 
    static public Nota GenereazaNota(int nota){
        return new Nota(nota);
    }
 
}
 
class Nota{
    int n;
 
    Nota(int nota) {
        n = nota;
    }
 
    public String toString(){
        return "Nota "+n;
    }