Diferença entre uma interface e uma classe abstrata em Java

Mohammad Irfan 12 outubro 2023
  1. Semelhanças entre classe abstrata e interface
  2. Diferenças entre classe abstrata e interface
  3. Quando usar a classe e interface abstratas?
  4. Classe abstrata em Java
  5. Interface em Java
  6. Classe abstrata que implementa uma interface
  7. Resumo
Diferença entre uma interface e uma classe abstrata em Java

Este tutorial apresenta a diferença entre uma interface e uma classe abstrata em Java e também lista alguns códigos de exemplo para entender o tópico.

Abstração é o processo de ocultar a implementação e apenas fornecer detalhes essenciais ao usuário. A abstração em Java é obtida por meio de classes abstratas e interfaces. Classes abstratas e interfaces têm algumas coisas em comum, mas existem grandes diferenças entre elas. Vamos primeiro examinar algumas das coisas que são semelhantes entre os dois.

Semelhanças entre classe abstrata e interface

  • Conforme discutido acima, tanto a classe abstrata quanto a interface são usadas para abstração.
  • Classes abstratas e interfaces não podem ser instanciadas, ou seja, não podemos criar um objeto para elas.
  • As subclasses devem substituir os métodos abstratos definidos na classe ou interface abstrata.

Os pontos acima resumem muito bem as semelhanças entre os dois. Vejamos agora algumas das principais diferenças entre eles.

Diferenças entre classe abstrata e interface

Classe abstract Interface
A palavra-chave abstract em Java é usada para criar ou declarar uma classe Abstract. Em Java, a palavra-chave interface é usada para criar ou declarar uma nova interface.
Uma classe pode herdar as propriedades e métodos de uma classe abstrata usando a palavra-chave extends. Para implementar uma Interface em Java, podemos usar a palavra-chave implements.
Uma classe abstrata pode ter métodos abstratos ou não abstratos definidos nela. Métodos abstratos são aqueles que não possuem nenhuma implementação fornecida para eles. Uma interface só pode conter métodos abstratos. Podemos apenas fornecer a definição do método, mas não sua implementação. Depois do Java 8, também podemos ter métodos padrão e estáticos nas interfaces.
Uma classe abstrata pode conter variáveis ​​finais ou não finais (atributos de classe). Ele também pode conter atributos estáticos ou não estáticos. Uma interface pode conter apenas membros estáticos e finais, e nenhum outro tipo de membro é permitido.
Uma classe abstrata pode implementar uma interface e implementar os métodos da interface. Uma interface não pode estender nenhuma outra classe e não pode substituir ou implementar métodos de classe abstratos.
Uma classe abstrata pode estender outras classes e também implementar interfaces. Conforme discutido no ponto anterior, as interfaces não podem estender outras classes. Mas não há nenhuma restrição na implementação de uma interface.
Java não oferece suporte a várias heranças por meio de classes. As classes abstratas, assim como qualquer outra classe, não oferecem suporte a várias heranças. O suporte para várias heranças em Java é fornecido por meio de interfaces. Isso ocorre porque as interfaces fornecem abstração completa.
Os membros ou atributos da classe abstrata podem ser privados, protegidos ou públicos. Atributos ou membros de uma interface são sempre públicos.

Quando usar a classe e interface abstratas?

As classes abstratas podem fornecer abstração parcial ou total. As interfaces, por outro lado, sempre fornecem abstração completa. Uma classe pai abstrata pode ser criada para algumas classes que possuem algumas funcionalidades comuns. Classes abstratas também são preferidas se você quiser mais liberdade de ação.

As interfaces são preferidas quando queremos definir uma estrutura básica. O programador pode então construir qualquer coisa com essa estrutura. As interfaces também oferecem suporte a várias heranças. Portanto, uma única classe pode implementar várias interfaces.

No geral, é uma questão de escolha e da tarefa que precisa ser realizada. Tanto a classe Abstract quanto a Interface são adequadas para finalidades diferentes e devem ser usadas de acordo.

Classe abstrata em Java

Vamos criar uma classe Abstract e criar classes filhas que a estendem para entender a classe abstrata e suas funcionalidades.

abstract class Bell {
  protected String sound;

  Bell() {
    this.sound = "ting";
  }
  // Abstract Method
  abstract public void ring();

  // Non-Abstract Methods
  public void increaseVolume() {
    System.out.println("Increasing Volume");
  }

  public void decreaseVolume() {
    System.out.println("Decreasing Volume");
  }
}
class SchoolBell extends Bell {
  @Override
  public void ring() {
    System.out.println("Ringing the School bell: " + sound);
  }
}
class ChruchBell extends Bell {
  @Override
  public void ring() {
    System.out.println("Ringing the Chruch Bell: " + sound);
  }
}
public class AbstractClassDemo {
  public static void main(String[] args) {
    SchoolBell sb = new SchoolBell();
    ChruchBell cb = new ChruchBell();

    // Using the overridden methods
    sb.ring();
    cb.ring();

    // Using the non-abstract methods of Bell class
    sb.increaseVolume();
    cb.decreaseVolume();
  }
}

Produção:

Ringing the School bell: ting
Ringing the Chruch Bell: ting
Increasing Volume
Decreasing Volume

Interface em Java

Vamos replicar o mesmo cenário usando interfaces. Não podemos mais definir métodos não abstratos na interface. Interface é a escolha correta se as classes não desejam uma implementação comum dos métodos boostVolume() e reduceVolume().

interface Bell {
  String sound = "ting";
  // only abstract methods allowed in interface
  public void ring();
  public void increaseVolume();
  public void decreaseVolume();
}
class SchoolBell implements Bell {
  public void ring() {
    System.out.println("Ringing the School bell: " + sound);
  }
  @Override
  public void increaseVolume() {
    System.out.println("Increasing Volume of School Bell");
  }
  @Override
  public void decreaseVolume() {
    System.out.println("Decreasing Volume of School Bell");
  }
}
class ChruchBell implements Bell {
  public void ring() {
    System.out.println("Ringing the Chruch Bell: " + sound);
  }
  @Override
  public void increaseVolume() {
    System.out.println("Increasing Volume of Chruch Bell");
  }
  @Override
  public void decreaseVolume() {
    System.out.println("Decreasing Volume of Chruch Bell");
  }
}
public class InterfaceDemo {
  public static void main(String[] args) {
    SchoolBell sb = new SchoolBell();
    ChruchBell cb = new ChruchBell();

    // Using the overridden methods
    sb.ring();
    cb.ring();

    // Using the non-abstract methods of Bell class
    sb.increaseVolume();
    cb.decreaseVolume();
  }
}

Produção:

Ringing the School bell: ting
Ringing the Chruch Bell: ting
Increasing Volume of School Bell
Decreasing Volume of Chruch Bell

Classe abstrata que implementa uma interface

Conforme discutido na seção anterior, podemos implementar os métodos de uma interface em uma classe abstrata. O código a seguir demonstra isso.

interface Bell {
  String sound = "ting";
  // only abstract methods allowed in interface
  public void ring();
  public void increaseVolume();
  public void decreaseVolume();
}
abstract class AbstractBell implements Bell {
  public void increaseVolume() {
    System.out.println("Increasing Volume");
  }
  public void decreaseVolume() {
    System.out.println("Decreasing Volume");
  }
}

Resumo

Abstração é um dos conceitos mais fundamentais usados ​​na programação orientada a objetos. A abstração é usada para ocultar a implementação e fornecer apenas os detalhes essenciais mínimos para o usuário. Em Java, a abstração é realizada usando classes abstratas ou interfaces. A principal diferença entre as duas é que as classes Abstract também podem fornecer abstração parcial, enquanto Interface sempre fornecerá abstração completa. Neste tutorial, discutimos algumas das principais diferenças entre os dois.

Artigo relacionado - Java Interface