DEV Community

Métodos padrão das interfaces e Fundamentos dos métodos padrão e exemplos

Métodos padrão das interfaces
Introdução no JDK 8:

  • Métodos padrão permitem que interfaces forneçam uma implementação padrão para um método.
  • Esse recurso resolve problemas de compatibilidade ao expandir interfaces sem quebrar códigos existentes.

Motivações:

  • Compatibilidade retroativa: Adicionar novos métodos a interfaces populares sem invalidar código existente.
  • Métodos opcionais: Permitir que certas implementações sejam opcionais, especialmente em casos de métodos irrelevantes para algumas classes que implementam a interface.

Exemplo de código:



// Interface com método padrão
interface MyInterface {
    void abstractMethod();

    // Método padrão
    default void defaultMethod() {
        System.out.println("Default implementation.");
    }
}

class MyClass implements MyInterface {
    public void abstractMethod() {
        System.out.println("Implemented abstract method.");
    }

    // Pode sobrescrever o método padrão, se necessário
    public void defaultMethod() {
        System.out.println("Overridden default method.");
    }
}

class DefaultMethodDemo {
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        obj.abstractMethod();
        obj.defaultMethod();
    }
}



Enter fullscreen mode Exit fullscreen mode

Ponto importante: Interfaces ainda não podem ter variáveis de instância, e continuam servindo principalmente para especificar o quê, e não como algo deve ser feito.

Fundamentos dos Métodos Padrão

Métodos padrão foram introduzidos no JDK 8.
Palavra-chave default: É usada para definir um método padrão em uma interface.
Objetivo: Permitir que as interfaces evoluam sem quebrar códigos existentes.
Implementação padrão: Fornece um corpo ao método que será utilizado caso a classe que implementa a interface não sobreponha o método.

Exemplo Básico de Método Padrão



public interface MyIF {
    // Método de interface comum, sem implementação.
    int getUserID();

    // Método padrão, com implementação fornecida.
    default int getAdminID() {
        return 1;
    }
}

class MyIFImp implements MyIF {
    // Apenas o método getUserID precisa ser implementado.
    public int getUserID() {
        return 100;
    }
}

class DefaultMethodDemo {
    public static void main(String args[]) {
        MyIFImp obj = new MyIFImp();
        System.out.println("User ID is " + obj.getUserID());
        System.out.println("Administrator ID is " + obj.getAdminID());
    }
}



Enter fullscreen mode Exit fullscreen mode

Saída:
User ID is 100
Administrator ID is 1

Explicação:

  • O método getAdminID() tem uma implementação padrão. A classe MyIFImp não precisa sobrescrever esse método, pois já existe um comportamento fornecido.
  • A classe MyIFImp só precisa implementar o método getUserID(), enquanto getAdminID() pode ser utilizado diretamente com a implementação padrão.

Sobrescrevendo Métodos Padrão
Sobrescrita de método padrão: A classe pode fornecer sua própria implementação, sobrescrevendo o método padrão.

Exemplo de Sobrescrita de Método Padrão



class MyIFImp2 implements MyIF {
    public int getUserID() {
        return 100;
    }

    // Sobrescreve o método padrão.
    public int getAdminID() {
        return 42;
    }
}

class DefaultMethodOverrideDemo {
    public static void main(String args[]) {
        MyIFImp2 obj = new MyIFImp2();
        System.out.println("User ID is " + obj.getUserID());
        System.out.println("Administrator ID is " + obj.getAdminID());
    }
}



Enter fullscreen mode Exit fullscreen mode

Saída:
User ID is 100
Administrator ID is 42

Explicação:
A implementação de getAdminID() foi sobrescrita em MyIFImp2, portanto, ao chamar esse método, ele retorna 42 ao invés do valor padrão 1.

Exemplo Prático de Método Padrão

  • Cenário Prático: Adição de métodos padrão em uma interface existente para evitar a quebra de código legado.
  • Interface Series: Define métodos que lidam com uma sequência de números. Um método padrão getNextArray() foi adicionado para retornar um array com os próximos n números da sequência, usando o método getNext() já existente.

Exemplo de Método Padrão em um Cenário Prático



public interface Series {
    int getNext(); // Retorna o próximo número da série.

    // Método padrão que retorna um array com os próximos n números.
    default int[] getNextArray(int n) {
        int[] vals = new int[n];
        for(int i = 0; i < n; i++) {
            vals[i] = getNext();
        }
        return vals;
    }

    void reset(); // Reinicia a série.
    void setStart(int x); // Define o valor inicial.
}

class ByTwos implements Series {
    int start;
    int val;

    ByTwos() {
        start = 0;
        val = 0;
    }

    public int getNext() {
        val += 2;
        return val;
    }

    public void reset() {
        val = start;
    }

    public void setStart(int x) {
        start = x;
        val = x;
    }
}

class SeriesDemo {
    public static void main(String args[]) {
        ByTwos ob = new ByTwos();
        int[] nextNums = ob.getNextArray(5);
        for(int n : nextNums) {
            System.out.print(n + " ");
        }
    }
}



Enter fullscreen mode Exit fullscreen mode

Saída:
2 4 6 8 10

Explicação:
A interface Series foi estendida com o método padrão getNextArray(), que usa o método getNext() para obter os próximos n números da série.
O código implementa a sequência de números pares e utiliza o novo método para obter um array com os próximos 5 números.

Vantagens dos Métodos Padrão

  • Evolução das interfaces sem quebrar código existente: Interfaces podem ser expandidas com novos métodos sem exigir alterações em classes que já as implementam.
  • Funcionalidade opcional: Permite que métodos sejam opcionais, sem necessidade de implementações de "espaço reservado".
  • Flexibilidade: Classes podem usar os métodos padrão como estão ou sobrescrevê-los conforme necessário.

Top comments (0)