Atualizado: 26/07/2025

Este conteúdo é original e não foi gerado por inteligência artificial.

Interfaces em Java

No Java, a herança de classes é limitada: uma classe só pode herdar diretamente de uma única superclasse. Em linguagens como C++, existe herança múltipla de classes, mas no Java isso não é permitido.

Para oferecer mais flexibilidade, o Java conta com interfaces, que definem contratos de métodos (e constantes) que uma ou mais classes podem implementar. Uma classe pode implementar vários interfaces, independentemente de já herdar de outra classe.


O que é um interface

Um interface é um tipo especial que contém:

  • Constantes (implicitamente public static final)
  • Métodos abstratos (implicitamente public abstract)
  • Métodos com implementação (default methods)
  • Métodos estáticos
  • Métodos privados

Por padrão, todo método de um interface é público. Um interface não pode ter atributos de instância e não pode ser instanciado diretamente.


Criando um interface

Para definir um interface, usa-se a palavra-chave interface:

interface Printable {
    void print();
}

Aqui, print() não tem implementação. Qualquer classe que implemente Printable será obrigada a fornecer uma implementação concreta para print().


Implementando um interface

Uma classe implementa um interface usando implements:

public class Program {
    public static void main(String[] args) {
        Book b1 = new Book("Java. Complete Reference", "H. Schildt");
        b1.print();
    }
}

interface Printable {
    void print();
}

class Book implements Printable {
    String name;
    String author;

    Book(String name, String author) {
        this.name = name;
        this.author = author;
    }

    public void print() {
        System.out.printf("%s (%s)%n", name, author);
    }
}

⚠️ Importante: Se a classe não implementar todos os métodos do interface, ela deve ser declarada como abstract.


Usando variáveis de interface

Não é possível criar instâncias diretas de um interface:

Printable p = new Printable(); // Erro

Mas uma variável do tipo do interface pode armazenar objetos de qualquer classe que o implemente:

Printable printable = new Book("Java. Complete Reference", "H. Schildt");
printable.print(); // Java. Complete Reference (H. Schildt)

printable = new Journal("Foreign Policy");
printable.print(); // Foreign Policy

Isso permite trabalhar de forma polimórfica: o código usa o interface, mas a implementação concreta pode variar.


Casting com interfaces

Assim como com classes, é possível fazer casting entre variáveis de interface e classes concretas:

Printable p = new Journal("Foreign Affairs");
p.print();

// Para acessar métodos específicos de Journal
String name = ((Journal) p).getName();
System.out.println(name);

Se o método não está no interface, é preciso converter para a classe correspondente.


Métodos default

Até o Java 7, todos os métodos de interface precisavam ser implementados pelas classes. A partir do Java 8, é possível criar métodos com implementação padrão usando default:

interface Printable {
    default void print() {
        System.out.println("Undefined printable");
    }
}

A classe que implementar esse interface pode sobrescrever o método ou herdar a implementação padrão.


Métodos estáticos em interfaces

Um interface pode ter métodos estáticos, chamados pelo próprio nome do interface:

interface Printable {
    static void read() {
        System.out.println("Read printable");
    }
}

Printable.read();

Métodos privados em interfaces

Métodos privados em interfaces servem para reutilizar código dentro do próprio interface. Eles não podem ser chamados de fora.

interface Calculatable {
    default int sum(int a, int b) {
        return sumAll(a, b);
    }
    default int sum(int a, int b, int c) {
        return sumAll(a, b, c);
    }
    private int sumAll(int... values) {
        int result = 0;
        for (int n : values) result += n;
        return result;
    }
}

Constantes em interfaces

As constantes declaradas em interfaces são sempre public static final:

interface Stateable {
    int OPEN = 1;
    int CLOSED = 0;
    void printState(int state);
}

class WaterPipe implements Stateable {
    public void printState(int n) {
        if (n == OPEN) System.out.println("Water is opened");
        else if (n == CLOSED) System.out.println("Water is closed");
        else System.out.println("State is invalid");
    }
}

Implementando múltiplos interfaces

Uma classe pode implementar mais de um interface, separados por vírgula:

class Book implements Printable, Searchable {
    // implementação
}

Herança entre interfaces

Interfaces também podem estender outros interfaces:

interface BookPrintable extends Printable {
    void paint();
}

A classe que implementar BookPrintable precisará implementar também os métodos de Printable.


Interfaces aninhadas

Interfaces podem ser declaradas dentro de classes ou outros interfaces:

class Printer {
    interface Printable {
        void print();
    }
}

class Journal implements Printer.Printable {
    String name;
    Journal(String name) {
        this.name = name;
    }
    public void print() {
        System.out.println(name);
    }
}

Interfaces como parâmetros e retorno

Assim como classes, interfaces podem ser usadas como tipo de parâmetro ou de retorno de métodos:

static void read(Printable p) {
    p.print();
}

static Printable createPrintable(String name, boolean option) {
    if (option) {
        return new Book(name, "Undefined");
    } else {
        return new Journal(name);
    }
}
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com