Como devo ter explicado a diferença entre uma interface e uma classe abstrata?

469

Em uma de minhas entrevistas, fui solicitado a explicar a diferença entre uma classe Interface e uma aula Abstrata .

Aqui está a minha resposta:

Os métodos de uma interface Java são implicitamente abstratos e não podem ter implementações. Uma classe abstrata Java pode ter métodos de instância que implementam um comportamento padrão.

As variáveis ​​declaradas em uma interface Java são, por padrão, finais. Uma classe abstrata pode conter variáveis ​​não finais.

Membros de uma interface Java são públicos por padrão. Uma classe abstrata Java pode ter os sabores usuais dos membros da classe, como privado, protegido etc.

Uma interface Java deve ser implementada usando a palavra-chave "implementa"; Uma classe abstrata de Java deve ser estendida usando a palavra-chave “extends”.

Uma interface pode estender apenas outra interface Java, uma classe abstrata pode estender outra classe Java e implementar várias interfaces Java.

Uma classe Java pode implementar várias interfaces, mas pode estender apenas uma classe abstrata.

No entanto, o entrevistador não ficou satisfeito e disse-me que essa descrição representava " conhecimento livreiro ".

Ele me pediu uma resposta mais prática, explicando quando eu escolheria uma aula abstrata em vez de uma interface, usando exemplos práticos .

Onde foi que eu errei?

Pensador
fonte
32
Talvez sua resposta parecesse estar dizendo algo que você não entende? Pode ser que você simplesmente precise mudar o estilo de contar para aquele que mais se parece com suas próprias palavras.
Kirill Kobelev
19
Você respondeu com uma lista de diferenças técnicas (bastante corretas). O entrevistador provavelmente estava procurando uma resposta mais conceitual (por exemplo, em que base alguém escolheria entre usar uma interface e uma classe abstrata).
Ted Hopp
15
Você esqueceu de dizer que as classes abstratas têm construtores, mesmo que você não possa instanciar uma classe abstrata, a const. é usado por classes filho. As interfaces indicam "o quê", mas não "como", porque definem um contrato (lista de métodos) enquanto abst. A classe também pode indicar "como" (implementar uma meta). Usando int. você pode emular uma herança múltipla (uma classe pode implementar várias int., mas apenas estender uma classe). Usando int. você pode ter um tipo de base para dif. famílias: Flyer f = novo plano (); Flyer f2 = novo pássaro (); Aves e Aviões não correspondem à mesma família, mas ambos podem voar (são folhetos).
Francisco Goldenstein
7
As interfaces java8 podem conter métodos. Portanto, além do conceito OO, as chamadas "diferenças" podem mudar a qualquer dia.
portador do anel
15
Não tenho nenhum problema com a sua resposta e não acho que o entrevistador possa negar o 'conhecimento do livro'. Os entrevistadores nem sempre sabem as respostas corretas para as perguntas que fazem, e algumas entrevistas servem apenas para avisá-lo para não trabalhar lá.
Marquês de Lorne

Respostas:

513

Vou dar um exemplo primeiro:

public interface LoginAuth{
   public String encryptPassword(String pass);
   public void checkDBforUser();
}

Suponha que você tenha 3 bancos de dados em seu aplicativo. Cada implementação desse banco de dados precisa definir os 2 métodos acima:

public class DBMySQL implements LoginAuth{
          // Needs to implement both methods
}
public class DBOracle implements LoginAuth{
          // Needs to implement both methods
}
public class DBAbc implements LoginAuth{
          // Needs to implement both methods
}

Mas e se encryptPassword()não for dependente do banco de dados e for o mesmo para cada classe? Então, o exposto acima não seria uma boa abordagem.

Em vez disso, considere esta abordagem:

public abstract class LoginAuth{
   public String encryptPassword(String pass){
            // Implement the same default behavior here 
            // that is shared by all subclasses.
   }

   // Each subclass needs to provide their own implementation of this only:
   public abstract void checkDBforUser();
}

Agora, em cada classe filho, precisamos implementar apenas um método - o método que depende do banco de dados.

Vimal Bera
fonte
97
Não sei se isso realmente explica a diferença ... é uma boa técnica. Suponho que também vale a pena salientar que o Java 8 finalmente admitiu que o C ++ estava certo e que várias heranças podem ser feitas e podem ter um uso, e agora as interfaces podem definir não apenas assinaturas de funções, mas também fornecer implementações padrão. Como tal, seria preferível usar uma interface.
Thecoshman
1
@thecoshman Que diferença faria se eu abordasse o problema como na resposta (classe abstrata com um método implementado e o outro abstrato) ou definisse uma interface com uma implementação padrão do método? Basicamente, o que estou tentando dizer é que você escreveu que 'seria preferível usar uma interface' e minha pergunta é - por que?
Neutrino 08/04
1
Então, acho que é justo dizer então que, com interfaces, a implementação do que foi definido depende da classe que realmente implementa a interface, enquanto as coisas em uma classe abstrata são "essenciais" para as classes que estendem a classe; isto é, não muda.
Orrymr
4
@Neutrino Apesar do Java permitir que você implemente várias interfaces, cada uma oferecendo implementações padrão para funções, você ainda pode estender apenas uma única classe. Dessa forma, o uso de uma interface pode fornecer mais flexibilidade para quem deseja usá-la, além de outras interfaces.
Thecoshman
3
@HiradNikoo Desculpe pelo comentário tardio, mas eu apenas tropecei neste tópico. Você também pode considerar a herança de classe como um relacionamento IS-A, enquanto as interfaces significam "tem uma certa funcionalidade".
precisa
206

Nada é perfeito neste mundo. Eles podem estar esperando uma abordagem mais prática.

Mas após a sua explicação, você pode adicionar essas linhas com uma abordagem ligeiramente diferente.

  1. Interfaces são regras (regras porque você deve dar uma implementação a elas que não pode ignorar ou evitar, para que sejam impostas como regras), que funciona como um documento de entendimento comum entre várias equipes no desenvolvimento de software.

  2. As interfaces dão a idéia do que deve ser feito, mas não como será feito. Portanto, a implementação depende completamente do desenvolvedor, seguindo as regras fornecidas (significa assinatura de métodos).

  3. As classes abstratas podem conter declarações abstratas, implementações concretas ou ambas.

  4. Declarações abstratas são como regras a serem seguidas e implementações concretas são como diretrizes (você pode usá-lo como está ou pode ignorá-lo, substituindo-o e fornecendo sua própria implementação).

  5. Além disso, quais métodos com a mesma assinatura podem alterar o comportamento em diferentes contextos são fornecidos como declarações de interface e como regras a serem implementadas em diferentes contextos.

Edit: Java 8 facilita a definição de métodos padrão e estáticos na interface.

public interface SomeInterfaceOne {

    void usualAbstractMethod(String inputString);

    default void defaultMethod(String inputString){
        System.out.println("Inside SomeInterfaceOne defaultMethod::"+inputString);
    }
}

Agora, quando uma classe implementará SomeInterface, não é obrigatório fornecer implementação para métodos padrão de interface.

Se tivermos outra interface com os seguintes métodos:

public interface SomeInterfaceTwo {

    void usualAbstractMethod(String inputString);

    default void defaultMethod(String inputString){
        System.out.println("Inside SomeInterfaceTwo defaultMethod::"+inputString);
    }

}

Java não permite estender várias classes porque resulta no "Problema de Diamante", em que o compilador não pode decidir qual método de superclasse usar. Com os métodos padrão, o problema do diamante também surgirá para as interfaces. Porque se uma classe está implementando ambos

SomeInterfaceOne and SomeInterfaceTwo

e não implementa o método padrão comum, o compilador não pode decidir qual escolher. Para evitar esse problema, no java 8 é obrigatório implementar métodos padrão comuns de diferentes interfaces. Se alguma classe estiver implementando as duas interfaces acima, ela deverá fornecer implementação para o método defaultMethod (), caso contrário, o compilador lançará um erro de tempo de compilação.

Shailesh Saxena
fonte
11
+1, esta é realmente uma boa resposta para evitar a confusão. Mas eu não vi nenhum link e não faço ideia do por que você citou essas linhas valiosas. Faça-os como pontos, se possível :).
Suresh Atta
Leia meu comentário acima sobre a emulação de herança múltipla usando interfaces e usando interfaces para ter um tipo base para classes de famílias diferentes. Eu acho que o entrevistador quer ouvir esse tipo de respostas dos entrevistados.
Francisco Goldenstein
Seu comentário também aponta para um bom exemplo de uso da interface. Escrevi o que sinto enquanto trabalhava dia a dia. Essas palavras podem não ser profissionais ou precisas. Mas é o que eu descobri depois de trabalhar em estreita colaboração com classes abstratas e interfaces na minha codificação diária.
Shailesh Saxena
4. Implementações concretas também são as regras, tendo a implementação padrão.
Luten 25/09/14
@Luten: De acordo com o meu conhecimento, se você pode evitar / ignorar uma regra sem nenhum problema, isso deve ser uma diretriz, não uma regra. Por favor corrija-me se eu estiver errado.
Shailesh Saxena 28/03
168

Você fez um bom resumo das diferenças práticas no uso e implementação, mas não disse nada sobre a diferença de significado.

Uma interface é uma descrição do comportamento que uma classe de implementação terá. A classe de implementação garante que terá esses métodos que podem ser usados ​​nela. É basicamente um contrato ou promessa que a classe tem que fazer.

Uma classe abstrata é uma base para diferentes subclasses que compartilham comportamentos que não precisam ser criados repetidamente. As subclasses devem concluir o comportamento e ter a opção de substituir o comportamento predefinido (desde que não seja definido como finalou private).

Você encontrará bons exemplos no java.utilpacote, que inclui interfaces como Liste classes abstratas como as AbstractListque já implementam a interface. A documentação oficial descreve o AbstractListseguinte:

Essa classe fornece uma implementação esquelética da interface List para minimizar o esforço necessário para implementar essa interface, apoiada por um armazenamento de dados de "acesso aleatório" (como uma matriz).

Daniel Lerps
fonte
16
Essa deve ser a resposta. Não é uma lista de detalhes, mas o conceito subjacente que faz a diferença entre uma interface e uma classe abstrata, não apenas em Java, mas em geral.
Edc65
1
Isto é muito bom. É claro que outras respostas também são boas. Mas isso indica um grande alerta sobre a abstractpalavra - chave, ou seja, quando um compilador vê isso, eles sabem, as seguintes informações estão incompletas e precisam ser implementadas . As interfaces são sempre incompletas, mas as classes abstratas são abstratas porque precisavam ter incomplete (abstract)métodos.
Rakib 25/04/19
85

Uma interface consiste em variáveis ​​singleton (final estático público) e métodos abstratos públicos. Normalmente, preferimos usar uma interface em tempo real quando sabemos o que fazer, mas não sabemos como fazê-lo .

Este conceito pode ser melhor entendido por exemplo:

Considere uma classe de pagamento. O pagamento pode ser feito de várias maneiras, como PayPal, cartão de crédito, etc. Portanto, normalmente aceitamos Payment como nossa interface, que contém um makePayment()método, e CreditCard e PayPal são as duas classes de implementação.

public interface Payment
{
    void makePayment();//by default it is a abstract method
}
public class PayPal implements Payment
{
    public void makePayment()
    {
        //some logic for PayPal payment
        //e.g. Paypal uses username and password for payment
    }
}
public class CreditCard implements Payment
{
    public void makePayment()
    {
        //some logic for CreditCard payment
        //e.g. CreditCard uses card number, date of expiry etc...
    }
}

No exemplo acima, CreditCard e PayPal são duas classes / estratégias de implementação. Uma interface também nos permite o conceito de herança múltipla em Java que não pode ser realizada por uma classe abstrata.

Escolhemos uma classe abstrata quando existem alguns recursos para os quais sabemos o que fazer e outros que sabemos executar .

Considere o seguinte exemplo:

public abstract class Burger
{
    public void packing()
    {
        //some logic for packing a burger
    }
    public abstract void price(); //price is different for different categories of burgers
}
public class VegBerger extends Burger
{
    public void price()
    {
        //set price for a veg burger.
    }
}
public class NonVegBerger extends Burger
{
    public void price()
    {
        //set price for a non-veg burger.
    }
}

Se adicionarmos métodos (concreto / abstrato) no futuro a uma determinada classe abstrata, a classe de implementação não precisará alterar seu código. No entanto, se adicionarmos métodos em uma interface no futuro, devemos adicionar implementações a todas as classes que implementaram essa interface, caso contrário, ocorrerão erros de tempo de compilação.

Existem outras diferenças, mas essas são as principais que podem ter sido o que o entrevistador esperava. Espero que isso tenha sido útil.

Satya
fonte
1
Bem, essa resposta faz muito sentido, e é bem claro com o exemplo, quando decidimos escolher entre interfacee abstract class.
MAC
"o que fazer, mas não sei como fazê-lo", pois definimos um método sem fazer implementações nele "void makePayment ();", enquanto definimos as implementações do método na classe que implementará a interface.
Abdel-Raouf
45

Diferença entre classe e interface Abstact

  1. Classes abstratas versus interfaces em Java 8
  2. Diferença conceitual:

Métodos padrão da interface em Java 8

  1. O que é o método padrão?
  2. Erro de compilação do método ForEach resolvido usando o Método Padrão
  3. Método padrão e vários problemas de ambiguidade de herança
  4. Pontos importantes sobre os métodos padrão da interface java:

Método estático da interface Java

  1. Método estático da interface Java, exemplo de código, método estático versus método padrão
  2. Pontos importantes sobre o método estático da interface java:

Interfaces Funcionais Java



Classes abstratas versus interfaces em Java 8

As mudanças na interface do Java 8 incluem métodos estáticos e métodos padrão nas interfaces. Antes do Java 8, poderíamos ter apenas declarações de método nas interfaces. Mas a partir do Java 8, podemos ter métodos padrão e métodos estáticos nas interfaces.

Depois de introduzir o Método Padrão, parece que as interfaces e as classes abstratas são iguais. No entanto, eles ainda são conceito diferente no Java 8.

Classe abstrata pode definir construtor. Eles são mais estruturados e podem ter um estado associado a eles. Por outro lado, o método padrão pode ser implementado apenas nos termos da chamada de outros métodos de interface, sem referência ao estado de uma implementação específica. Portanto, ambos usam para finalidades diferentes e a escolha entre dois realmente depende do contexto do cenário.

Diferença conceitual:

As classes abstratas são válidas para implementações esqueléticas (isto é, parciais) de interfaces, mas não devem existir sem uma interface correspondente.

Portanto, quando as classes abstratas são efetivamente reduzidas a implementações esqueléticas de interfaces de baixa visibilidade, os métodos padrão também podem tirar isso? Decididamente: Não! A implementação de interfaces quase sempre requer algumas ou todas as ferramentas de criação de classe que faltam nos métodos padrão. E se alguma interface não funcionar, é claramente um caso especial, que não deve desviar você.

Métodos padrão da interface em Java 8

O Java 8 apresenta o novo recurso " Método Padrão " ou (métodos Defender), que permite ao desenvolvedor adicionar novos métodos às Interfaces sem interromper a implementação existente dessa Interface. Ele fornece flexibilidade para permitir que a Interface defina a implementação que será usada como padrão na situação em que uma Classe concreta falha ao fornecer uma implementação para esse método.

Vamos considerar um pequeno exemplo para entender como funciona:

public interface OldInterface {
    public void existingMethod();
 
    default public void newDefaultMethod() {
        System.out.println("New default method"
               + " is added in interface");
    }
}

A classe a seguir será compilada com êxito no Java JDK 8,

public class OldInterfaceImpl implements OldInterface {
    public void existingMethod() {
     // existing implementation is here…
    }
}

Se você criar uma instância de OldInterfaceImpl:

OldInterfaceImpl obj = new OldInterfaceImpl ();
// print “New default method add in interface”
obj.newDefaultMethod(); 

Método padrão:

Os métodos padrão nunca são finais, não podem ser sincronizados e não podem substituir os métodos do Object. Eles são sempre públicos, o que limita severamente a capacidade de escrever métodos curtos e reutilizáveis.

Os métodos padrão podem ser fornecidos a uma interface sem afetar as classes de implementação, pois incluem uma implementação. Se cada método adicionado em uma Interface definida com implementação, nenhuma Classe de implementação é afetada. Uma classe de implementação pode substituir a implementação padrão fornecida pela interface.

Os métodos padrão permitem adicionar nova funcionalidade às interfaces existentes sem interromper a implementação mais antiga dessas interfaces.

Quando estendemos uma interface que contém um método padrão, podemos executar os seguintes,

  1. Não substitui o método padrão e herdará o método padrão.
  2. Substitua o método padrão semelhante a outros métodos que substituímos na subclasse.
  3. Redefina o método padrão como abstrato, forçando a subclasse a substituí-lo.

Erro de compilação do método ForEach resolvido usando o Método Padrão

Para Java 8, as coleções JDK foram estendidas e o método forEach é incluído em toda a coleção (que funciona em conjunto com lambdas). Da maneira convencional, o código se parece abaixo,

public interface Iterable<T> {
    public void forEach(Consumer<? super T> consumer);
}

Como esse resultado, cada classe de implementação com erros de compilação, portanto, foi adicionado um método padrão com uma implementação necessária para que a implementação existente não fosse alterada.

A interface iterável com o método padrão está abaixo,

public interface Iterable<T> {
    public default void forEach(Consumer
                   <? super T> consumer) {
        for (T t : this) {
            consumer.accept(t);
        }
    }
}

O mesmo mecanismo foi usado para adicionar fluxo na interface JDK sem interromper as classes de implementação.


Método padrão e vários problemas de ambiguidade de herança

Como a classe java pode implementar várias interfaces e cada interface pode definir o método padrão com a mesma assinatura de método, portanto, os métodos herdados podem entrar em conflito entre si.

Considere o exemplo abaixo,

public interface InterfaceA {  
       default void defaultMethod(){  
           System.out.println("Interface A default method");  
    }  
}
 
public interface InterfaceB {
   default void defaultMethod(){
       System.out.println("Interface B default method");
   }
}
 
public class Impl implements InterfaceA, InterfaceB  {
}

O código acima falhará ao compilar com o seguinte erro,

java: class Impl herda padrões não relacionados para defaultMethod () dos tipos InterfaceA e InterfaceB

Para corrigir essa classe, precisamos fornecer a implementação do método padrão:

public class Impl implements InterfaceA, InterfaceB {
    public void defaultMethod(){
    }
}

Além disso, se quisermos chamar a implementação padrão fornecida por qualquer super interface, em vez de nossa própria implementação, podemos fazer o seguinte:

public class Impl implements InterfaceA, InterfaceB {
    public void defaultMethod(){
        // existing code here..
        InterfaceA.super.defaultMethod();
    }
}

Podemos escolher qualquer implementação padrão ou ambas como parte de nosso novo método.

Pontos importantes sobre os métodos padrão da interface java:

  1. Os métodos padrão da interface Java nos ajudarão a estender as interfaces sem medo de quebrar as classes de implementação.
  2. Os métodos padrão da interface Java eliminam as diferenças entre interfaces e classes abstratas.
  3. Os métodos padrão da interface Java 8 nos ajudarão a evitar classes de utilidade, como todo o método da classe Collections pode ser fornecido nas próprias interfaces.
  4. Os métodos padrão da interface Java nos ajudarão a remover as classes de implementação base, podemos fornecer a implementação padrão e as classes de implementação podem escolher qual substituir.
  5. Um dos principais motivos para a introdução de métodos padrão nas interfaces é aprimorar a API Collections no Java 8 para suportar expressões lambda.
  6. Se alguma classe na hierarquia tiver um método com a mesma assinatura, os métodos padrão se tornarão irrelevantes. Um método padrão não pode substituir um método de java.lang.Object. O raciocínio é muito simples, porque Object é a classe base para todas as classes java. Portanto, mesmo se tivermos métodos da classe Object definidos como métodos padrão nas interfaces, será inútil porque o método da classe Object sempre será usado. É por isso que, para evitar confusão, não podemos ter métodos padrão que estão substituindo os métodos da classe Object.
  7. Os métodos padrão da interface Java também são chamados de Métodos do Defender ou Métodos de extensão virtual.

Link do recurso:

  1. Interface com métodos padrão vs classe Abstract em Java 8
  2. Classe abstrata versus interface na era JDK 8
  3. Evolução da interface via métodos de extensão virtual

Método estático da interface Java

Método estático da interface Java, exemplo de código, método estático versus método padrão

O método estático da interface Java é semelhante ao método padrão, exceto que não podemos substituí-los nas classes de implementação. Esse recurso nos ajuda a evitar resultados indesejados, caso a implementação seja ruim nas classes de implementação. Vamos examinar isso com um exemplo simples.

public interface MyData {

    default void print(String str) {
        if (!isNull(str))
            System.out.println("MyData Print::" + str);
    }

    static boolean isNull(String str) {
        System.out.println("Interface Null Check");

        return str == null ? true : "".equals(str) ? true : false;
    }
}

Agora vamos ver uma classe de implementação que está tendo o método isNull () com implementação ruim.

public class MyDataImpl implements MyData {

    public boolean isNull(String str) {
        System.out.println("Impl Null Check");

        return str == null ? true : false;
    }

    public static void main(String args[]){
        MyDataImpl obj = new MyDataImpl();
        obj.print("");
        obj.isNull("abc");
    }
}

Observe que isNull (String str) é um método de classe simples, não substitui o método da interface. Por exemplo, se adicionarmos a anotação @Override ao método isNull (), isso resultará em erro do compilador.

Agora, quando executaremos o aplicativo, obtemos a seguinte saída.

Verificação nula da interface

Verificação nula impl.

Se fizermos o método da interface de estático para o padrão, obteremos a seguinte saída.

Verificação nula impl.

Impressão MyData ::

Verificação nula impl.

O método estático da interface Java é visível apenas para os métodos de interface. Se removermos o método isNull () da classe MyDataImpl, não poderemos usá-lo para o objeto MyDataImpl. No entanto, como outros métodos estáticos, podemos usar métodos estáticos de interface usando o nome da classe. Por exemplo, uma declaração válida será:

boolean result = MyData.isNull("abc");

Pontos importantes sobre o método estático da interface java:

  1. O método estático da interface Java faz parte da interface, não podemos usá-lo para objetos de classe de implementação.
  2. Os métodos estáticos da interface Java são bons para fornecer métodos utilitários, por exemplo, verificação nula, classificação de coleções etc.
  3. O método estático da interface Java nos ajuda a fornecer segurança, não permitindo que as classes de implementação as substituam.
  4. Não podemos definir o método estático da interface para os métodos da classe Object, obteremos um erro do compilador como "Este método estático não pode ocultar o método da instância do Object". Isso ocorre porque não é permitido em java, pois Object é a classe base de todas as classes e não podemos ter um método estático no nível de classe e outro método de instância com a mesma assinatura.
  5. Podemos usar métodos estáticos da interface java para remover classes de utilitários como Collections e mover todos os seus métodos estáticos para a interface correspondente, que seria fácil de encontrar e usar.

Interfaces Funcionais Java

Antes de concluir o post, gostaria de fornecer uma breve introdução às interfaces funcionais. Uma interface com exatamente um método abstrato é conhecida como Interface Funcional.

Uma nova anotação @FunctionalInterfacefoi introduzida para marcar uma interface como Interface Funcional.@FunctionalInterfaceA anotação é um recurso para evitar a adição acidental de métodos abstratos nas interfaces funcionais. É opcional, mas é uma boa prática usá-lo.

As interfaces funcionais são muito aguardadas e muito procuradas pelo Java 8, pois nos permite usar expressões lambda para instancia-las. Um novo pacote java.util.function com várias interfaces funcionais é adicionado para fornecer tipos de destino para expressões lambda e referências de método. Examinaremos interfaces funcionais e expressões lambda nas próximas postagens.

Local do Recurso:

  1. Alterações na interface do Java 8 - método estático, método padrão
SkyWalker
fonte
8
Estou procurando exatamente esses tipos de respostas atualizadas. Obrigado pela resposta rápida.
Ravindra babu
41

Todas as suas instruções são válidas, exceto a sua primeira (após o lançamento do Java 8):

Os métodos de uma interface Java são implicitamente abstratos e não podem ter implementações

Na página de documentação :

Uma interface é um tipo de referência, semelhante a uma classe, que pode conter apenas constantes, assinaturas de métodos, métodos padrão, métodos estáticos e tipos aninhados

Os corpos dos métodos existem apenas para métodos padrão e métodos estáticos.

Métodos padrão:

Uma interface pode ter métodos padrão , mas são diferentes dos métodos abstratos nas classes abstratas.

Os métodos padrão permitem adicionar novas funcionalidades às interfaces de suas bibliotecas e garantir compatibilidade binária com o código gravado para versões mais antigas dessas interfaces.

Ao estender uma interface que contém um método padrão, você pode fazer o seguinte:

  1. Sem mencionar o método padrão, que permite que a interface estendida herde o método padrão.
  2. Redecare o método padrão, o que o faz abstract.
  3. Redefina o método padrão, que o substitui.

Métodos estáticos:

Além dos métodos padrão, você pode definir métodos estáticos nas interfaces. (Um método estático é um método associado à classe em que está definido, e não a qualquer objeto. Cada instância da classe compartilha seus métodos estáticos.)

Isso facilita a organização de métodos auxiliares em suas bibliotecas;

Código de exemplo da página de documentação sobre interfaceter statice defaultmétodos.

import java.time.*;

public interface TimeClient {
    void setTime(int hour, int minute, int second);
    void setDate(int day, int month, int year);
    void setDateAndTime(int day, int month, int year,
                               int hour, int minute, int second);
    LocalDateTime getLocalDateTime();

    static ZoneId getZoneId (String zoneString) {
        try {
            return ZoneId.of(zoneString);
        } catch (DateTimeException e) {
            System.err.println("Invalid time zone: " + zoneString +
                "; using default time zone instead.");
            return ZoneId.systemDefault();
        }
    }

    default ZonedDateTime getZonedDateTime(String zoneString) {
        return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
    }
}

Use as diretrizes abaixo para escolher se deseja usar uma interface ou classe abstrata.

Interface:

  1. Para definir um contrato (de preferência sem estado - não quero dizer variáveis)
  2. Vincular classes não relacionadas a tem recursos.
  3. Declarar variáveis ​​constantes públicas ( estado imutável )

Classe abstrata:

  1. Compartilhe código entre várias classes estreitamente relacionadas. Estabelece é uma relação.

  2. Compartilhar estado comum entre classes relacionadas (o estado pode ser modificado em classes concretas)

Mensagens relacionadas:

Interface versus classe abstrata (OO geral)

Implementos vs extensões: quando usar? Qual é a diferença?

Analisando esses exemplos, você pode entender que

As classes não relacionadas podem ter recursos por meio da interface, mas as classes relacionadas alteram o comportamento por meio da extensão das classes base.

Ravindra babu
fonte
O que você quer dizer com "contrato apátrida"? É o item 1 sobre interfaces
Maksim Dmitriev
1
Ausência de estado mutável. Desde interface pode ter constantes, os dados podem ser mutado ao contrário de classes abstratas
Ravindra babu
1
Correção na declaração acima. Na interface, Os dados não podem ser mutado ao contrário classe abstrata
Ravindra babu
2
Esta é a melhor resposta. Ele não apenas aborda o Java8, mas também explica em quais situações específicas você usaria um deles.
Shuklaswag 28/01
O conceito de statelessinterface é um sucesso. A interface não pode ter nenhum estado (a interface pode ter constantes, mas são finais / estáticas, portanto, imutáveis).
Kaihua
22

Sua explicação parece decente, mas pode parecer que você estava lendo tudo de um livro? : - /

O que mais me incomoda é: quão sólido foi o seu exemplo? Você se preocupou em incluir quase todas as diferenças entre abstrato e interfaces?

Pessoalmente, eu sugiro este link: http://mindprod.com/jgloss/interfacevsabstract.html#TABLE

para uma lista exaustiva de diferenças ..

Espero que ajude você e todos os outros leitores em suas futuras entrevistas

VictorCreator
fonte
1
o link é compartilhado é realmente incrível
Premraj
Você pode fornecer implementação padrão nas interfaces Java utilizando a palavra-chave padrão
Ogen
21

Muitos desenvolvedores juniores cometem o erro de pensar em interfaces, classes abstratas e concretas como pequenas variações da mesma coisa e escolhem uma delas puramente por motivos técnicos: Preciso de herança múltipla? Preciso de algum lugar para colocar métodos comuns? Preciso me preocupar com algo que não seja apenas uma aula concreta? Isso está errado, e oculto nessas perguntas está o principal problema: "eu" . Quando você escreve um código para si mesmo, raramente pensa em outros desenvolvedores atuais ou futuros trabalhando no seu código ou com ele.

As interfaces e as classes abstratas, embora aparentemente semelhantes do ponto de vista técnico, têm significados e propósitos completamente diferentes.

Sumário

  1. Uma interface define um contrato que alguma implementação cumprirá para você .

  2. Uma classe abstrata fornece um comportamento padrão que sua implementação pode reutilizar.

Esses dois pontos acima são o que estou procurando ao entrevistar e são um resumo compacto o suficiente. Continue lendo para mais detalhes.

Resumo alternativo

  1. Uma interface é para definir APIs públicas
  2. Uma classe abstrata é para uso interno e para definir SPIs

Por exemplo

Em outras palavras: uma classe concreta faz o trabalho real, de uma maneira muito específica. Por exemplo, umArrayList usa uma área contígua da memória para armazenar uma lista de objetos de maneira compacta, que oferece acesso aleatório rápido, iteração e alterações no local, mas é terrível em inserções, exclusões e, ocasionalmente, inclusões; enquanto isso, umLinkedListusa nós com vínculo duplo para armazenar uma lista de objetos, que oferecem iteração rápida, alterações no local e inserção / exclusão / adição, mas são terríveis no acesso aleatório. Esses dois tipos de lista são otimizados para diferentes casos de uso, e importa muito como você os usará. Ao tentar extrair o desempenho de uma lista com a qual você está interagindo intensamente, e ao escolher o tipo de lista é sua, você deve escolher com cuidado qual deles está instanciando.

Por outro lado, os usuários de alto nível de uma lista não se importam com como ela é realmente implementada e devem ser isolados desses detalhes. Vamos imaginar que o Java não expôs a Listinterface, mas só tinha uma Listclasse concreta que é realmente o que LinkedListé agora. Todos os desenvolvedores Java teriam adaptado seu código para atender aos detalhes da implementação: evite o acesso aleatório, adicione um cache para acelerar o acesso ou apenas reimplemente ArrayListpor conta própria, embora seja incompatível com todos os outros códigos que realmente funcionam Listapenas. Isso seria terrível ... Mas agora imagine que os mestres Java realmente percebam que uma lista vinculada é terrível para a maioria dos casos de uso reais e decidiram mudar para uma lista de matrizes apenas paraListclasse disponível. Isso afetaria o desempenho de todos os programas Java do mundo e as pessoas não ficariam felizes com isso. E o principal culpado é que os detalhes da implementação estavam disponíveis, e os desenvolvedores assumiram que esses detalhes são um contrato permanente em que podem confiar. É por isso que é importante ocultar os detalhes da implementação e definir apenas um contrato abstrato. Esse é o objetivo de uma interface: defina que tipo de entrada um método aceita e que tipo de saída é esperado, sem expor todas as tripas que tentariam os programadores a ajustar seu código para ajustar os detalhes internos que podem mudar com qualquer atualização futura .

Uma classe abstrata está no meio entre interfaces e classes concretas. Ele deve ajudar as implementações a compartilhar código comum ou chato. Por exemplo, AbstractCollectionfornece implementações básicas para o isEmptytamanho 0, containscomo iterar e comparar, addAllconforme repetido adde assim por diante. Isso permite que as implementações se concentrem nas partes cruciais que diferem entre elas: como realmente armazenar e recuperar dados.

Outra perspectiva: APIs versus SPIs

Interfaces são gateways de baixa coesão entre diferentes partes do código. Eles permitem que as bibliotecas existam e evoluam sem interromper todos os usuários da biblioteca quando algo muda internamente. Chama-se Interface de Programação de Aplicativos , não Classes de Programação de Aplicativos. Em uma escala menor, eles também permitem que vários desenvolvedores colaborem com sucesso em projetos de grande escala, separando diferentes módulos por meio de interfaces bem documentadas.

As classes abstratas são ajudantes de alta coesão a serem usadas na implementação de uma interface, assumindo algum nível de detalhes de implementação. Como alternativa, classes abstratas são usadas para definir SPIs, interfaces de provedor de serviços.

A diferença entre uma API e uma SPI é sutil, mas importante: para uma API, o foco está em quem a usa e, para uma SPI, está focada em quem a implementa .

É fácil adicionar métodos a uma API, todos os usuários existentes da API ainda serão compilados. É difícil adicionar métodos a um SPI, pois todo provedor de serviços (implementação concreta) precisará implementar os novos métodos. Se forem usadas interfaces para definir uma SPI, o provedor precisará liberar uma nova versão sempre que o contrato da SPI for alterado. Se classes abstratas forem usadas, novos métodos podem ser definidos em termos de métodos abstratos existentes ou como throw not implemented exceptionstubs vazios , o que permitirá pelo menos que uma versão mais antiga de uma implementação de serviço ainda seja compilada e executada.

Uma observação sobre Java 8 e métodos padrão

Embora o Java 8 tenha introduzido métodos padrão para interfaces, o que torna a linha entre interfaces e classes abstratas ainda mais embaçada, isso não foi para que as implementações possam reutilizar o código, mas para facilitar a alteração de interfaces que servem tanto como API quanto como SPI (ou são usados ​​incorretamente para definir SPIs em vez de classes abstratas).

"Conhecimento do livro"

Os detalhes técnicos fornecidos na resposta do OP são considerados "conhecimento do livro", porque essa é geralmente a abordagem usada na escola e na maioria dos livros de tecnologia sobre um idioma: o que é importante, não como usá-lo na prática, especialmente em aplicações de grande escala .

Aqui está uma analogia: supunha que a pergunta era:

O que é melhor para alugar para a noite do baile, um carro ou um quarto de hotel?

A resposta técnica soa como:

Bem, em um carro você pode fazê-lo mais cedo, mas em um quarto de hotel, você pode fazê-lo com mais conforto. Por outro lado, o quarto do hotel fica em apenas um lugar, enquanto no carro você pode fazê-lo em mais lugares, como, digamos, que você pode ir ao ponto de vista para ter uma bela vista ou em um cinema drive-in, ou muitos outros lugares, ou mesmo em mais de um lugar. Além disso, o quarto do hotel tem um chuveiro.

Isso tudo é verdade, mas perde completamente os pontos de que são duas coisas completamente diferentes, e ambas podem ser usadas ao mesmo tempo para propósitos diferentes, e o aspecto "fazê-lo" não é a coisa mais importante em nenhuma das duas opções. . A resposta não tem perspectiva, mostra uma maneira imatura de pensar, enquanto apresenta corretamente "fatos" verdadeiros.

Sergiu Dumitriu
fonte
Você quis dizer "baixo acoplamento"?
precisa saber é o seguinte
@ user2418306 Não, coesão é um termo mais genérico que inclui acoplamento, embora sejam sinônimos estreitos, e qualquer um dos termos teria funcionado.
Sergiu Dumitriu 23/01
9

Que tal pensar da seguinte maneira:

  • Um relacionamento entre uma classe e uma classe abstrata é do tipo "is-a"
  • Um relacionamento entre uma classe e uma interface é do tipo "has-a"

Então, quando você tem uma classe abstrata Mammals, uma subclasse Human e uma interface Driving, você pode dizer

  • cada humano é um mamífero
  • cada ser humano tem uma condução (comportamento)

Minha sugestão é que a frase de conhecimento do livro indique que ele queria ouvir a diferença semântica entre os dois (como outros aqui já sugeridos).

akohout
fonte
9

Uma interface é um "contrato" em que a classe que implementa o contrato promete implementar os métodos. Um exemplo em que eu tive que escrever uma interface em vez de uma classe foi quando eu estava atualizando um jogo de 2D para 3D. Eu tive que criar uma interface para compartilhar classes entre as versões 2D e 3D do jogo.

package adventure;
import java.awt.*;
public interface Playable {
    public void playSound(String s);
    public Image loadPicture(String s);    
}

Então, eu posso implementar os métodos com base no ambiente, enquanto ainda consigo chamá-los de um objeto que não sabe qual versão do jogo está carregando.

public class Adventure extends JFrame implements Playable

public class Dungeon3D extends SimpleApplication implements Playable

public class Main extends SimpleApplication implements AnimEventListener, ActionListener, Playable

Normalmente, no mundo dos jogos, o mundo pode ser uma classe abstrata que executa métodos no jogo:

public abstract class World...

    public Playable owner;

    public Playable getOwner() {
        return owner;
    }

    public void setOwner(Playable owner) {
        this.owner = owner;
    }
Niklas R.
fonte
6

As classes abstratas não são pura abstração, pois sua coleção de métodos concretos (métodos implementados) e não implementados. Mas as interfaces são pura abstração, pois existem apenas métodos não implementados, não métodos concretos.

Por que aulas abstratas?

  1. Se o usuário desejar escrever funcionalidade comum para todos os objetos.
  2. Classes abstratas são a melhor opção para reimplementação no futuro, para adicionar mais funcionalidades sem afetar o usuário final.

Por que interfaces?

  1. Se o usuário quiser escrever uma funcionalidade diferente, isso seria diferente nos objetos.
  2. As interfaces são a melhor opção que, se não for necessário, modificar os requisitos após a publicação da interface.
Sarfaraz Ahamad
fonte
5

Uma interface é como um conjunto de genes documentados publicamente para ter algum tipo de efeito: um teste de DNA me dirá se eu os tenho - e se eu tiver, posso publicamente divulgar que sou um portador "e parte do meu comportamento ou estado estará em conformidade com eles. (Mas é claro, eu posso ter muitos outros genes que fornecem características fora desse escopo.)

Uma classe abstrata é como o ancestral morto de uma espécie do mesmo sexo (*): ela não pode ser trazida à vida, mas um descendente vivo (isto é, não abstrato ) herda todos os seus genes.

(*) Para esticar essa metáfora, digamos que todos os membros da espécie vivem na mesma idade. Isso significa que todos os ancestrais de um ancestral morto também devem estar mortos - e da mesma forma, todos os descendentes de um ancestral vivo devem estar vivos.

Steve Chambers
fonte
4

Eu faço entrevistas para o trabalho e eu ficaria desfavorável em sua resposta também (desculpe, mas sou muito honesto). Parece que você leu sobre a diferença e revisou uma resposta, mas talvez você nunca a tenha usado na prática.

Uma boa explicação de por que você usaria cada um pode ser muito melhor do que ter uma explicação precisa da diferença. Os empregadores ultimatley querem que os programadores façam coisas que não os conhecem e que podem ser difíceis de demonstrar em uma entrevista. A resposta que você deu seria boa se se candidatasse a um trabalho técnico ou baseado em documentação, mas não na função de desenvolvedor.

Boa sorte com entrevistas no futuro.

Além disso, minha resposta a essa pergunta é mais sobre a técnica da entrevista, em vez do material técnico que você forneceu. Talvez considere ler sobre isso. https://workplace.stackexchange.com/ pode ser um excelente lugar para esse tipo de coisa.

Adrian
fonte
1
Você poderia me dizer como você respondeu? Pode ser que possa me ajudar.
code_fish
dar a você a resposta oferece muito menos do que ajudá-lo a resolvê-lo, basicamente dê um exemplo prático de quando você usaria cada um e explique por que cada um é adequado para as diferentes tarefas.
Adrian
4

Você escolhe Interface em Java para evitar o problema do diamante na herança múltipla .

Se você deseja que todos os seus métodos sejam implementados pelo seu cliente, opte pela interface. Isso significa que você projeta o aplicativo inteiro em resumo.

Você escolhe a classe abstrata se já sabe o que está em comum. Por exemplo, pegue uma classe abstrata Car. No nível superior, você implementa os métodos comuns de carro, como calculateRPM(). É um método comum e você permite que o cliente implemente seu próprio comportamento, como
calculateMaxSpeed()etc. Provavelmente, você explicaria dando alguns exemplos em tempo real que encontrou no seu trabalho do dia a dia.

MaheshVarma
fonte
3

A principal diferença que observei foi que a classe abstrata nos fornece algum comportamento comum já implementado e as subclasses precisam apenas implementar funcionalidades específicas correspondentes a elas. onde, quanto a uma interface, especificará apenas quais tarefas precisam ser executadas e nenhuma implementação será dada por ela. Posso dizer que especifica o contrato entre si e as classes implementadas.


fonte
3

Até eu já enfrentei a mesma pergunta em várias entrevistas e, acredite, torna seu tempo miserável para convencer o entrevistador. Se eu herdar todas as respostas acima, preciso adicionar mais um ponto-chave para torná-lo mais convincente e utilizar o melhor da OO

Caso você não esteja planejando nenhuma modificação nas regras , para que a subclasse seja seguida, por um longo futuro, vá para a interface, pois você não poderá modificá-la e, se fizer isso, precisará ir para o alterações em todas as outras subclasses, enquanto que, se você pensar, deseja reutilizar a funcionalidade, definir algumas regras e também torná-la aberta para modificação , vá para a classe Abstract.

Pense dessa maneira: você utilizou um serviço consumível ou forneceu algum código ao mundo e você tem a chance de modificar alguma coisa, suponha uma verificação de segurança. E se eu sou consumidor do código e encontre todas as marcas de leitura no meu Eclipse, todo o aplicativo está inoperante. Portanto, para evitar esses pesadelos, use Abstract over Interfaces

Eu acho que isso pode convencer o entrevistador até certo ponto ... Entrevistas felizes à frente.

vinod bazari
fonte
2

Quando estou tentando compartilhar o comportamento entre duas classes estreitamente relacionadas, crio uma classe abstrata que mantém o comportamento comum e serve como pai das duas classes.

Quando estou tentando definir um Tipo, uma lista de métodos que um usuário do meu objeto pode chamar com segurança, eu crio uma interface.

Por exemplo, eu nunca criaria uma classe abstrata com 1 subclasse concreta, porque as classes abstratas são sobre o compartilhamento de comportamento. Mas eu poderia muito bem criar uma interface com apenas uma implementação. O usuário do meu código não saberá que existe apenas uma implementação. De fato, em uma versão futura, pode haver várias implementações, todas subclasses de alguma nova classe abstrata que nem existiam quando eu criei a interface.

Isso pode ter parecido um pouco muito estudioso também (embora eu nunca tenha visto isso dessa maneira em qualquer lugar que eu me lembre). Se o entrevistador (ou o OP) realmente quisesse mais da minha experiência pessoal nisso, eu estaria pronto com as histórias de uma interface que evoluiu por necessidade e vice-versa.

Mais uma coisa. O Java 8 agora permite inserir código padrão em uma interface, obscurecendo ainda mais a linha entre interfaces e classes abstratas. Mas, pelo que vi, esse recurso é usado em excesso mesmo pelos criadores das principais bibliotecas Java. Esse recurso foi adicionado, e com razão, para tornar possível estender uma interface sem criar incompatibilidade binária. Mas se você estiver criando um novo tipo definindo uma interface, a interface deverá ser APENAS uma interface. Se você também quiser fornecer código comum, faça uma classe auxiliar (abstrata ou concreta). Não bagunce sua interface desde o início com a funcionalidade que você deseja alterar.

Teto
fonte
2

A diferença básica entre interface e classe abstrata é que a interface suporta herança múltipla, mas a classe abstrata não.

Na classe abstrata, você também pode fornecer todos os métodos abstratos, como interface.

por que classe abstrata é necessária?

Em alguns cenários, ao processar a solicitação do usuário, a classe abstrata não sabe qual a intenção do usuário. Nesse cenário, definiremos um método abstrato na classe e solicitaremos ao usuário que estender essa classe, forneça sua intenção no método abstrato. Nesse caso, as classes abstratas são muito úteis

Por que a interface é necessária?

Digamos que tenho um trabalho que não tenho experiência nessa área. Por exemplo, se você deseja construir um edifício ou barragem, o que fará nesse cenário?

  1. você identificará quais são seus requisitos e fará um contrato com esses requisitos.
  2. Em seguida, ligue para os concursos para construir seu projeto
  3. Quem já construiu o projeto, deve atender às suas necessidades. Mas a lógica de construção é diferente de um fornecedor para outro.

Aqui não me importo com a lógica de como eles construíram. O objeto final atendeu aos meus requisitos ou não, apenas o meu ponto-chave.

Aqui, seus requisitos chamados interface e construtores são chamados de implementador.

Dharisi Suresh
fonte
2

Em poucas palavras, eu responderia assim:

  • herança via hierarquia de classes implica em herança de estado ;
  • considerando que herança via interfaces significa herança de comportamento ;

As classes abstratas podem ser tratadas como algo entre esses dois casos (ele introduz algum estado, mas também obriga a definir um comportamento); uma classe totalmente abstrata é uma interface (este é um desenvolvimento adicional de classes consistindo de métodos virtuais apenas em C ++ como até onde eu conheço sua sintaxe).

Obviamente, a partir do Java 8, as coisas mudaram um pouco, mas a ideia ainda é a mesma.

Eu acho que isso é bastante suficiente para uma entrevista típica de Java, se você não estiver sendo entrevistado para uma equipe de compiladores.

Gleb Stromov
fonte
1

Pelo que entendi, uma Interface, composta de variáveis ​​e métodos finais sem implementações, é implementada por uma classe para obter um grupo de métodos ou métodos relacionados entre si. Por outro lado, uma classe abstrata, que pode conter variáveis ​​e métodos não finais com implementações, geralmente é usada como um guia ou uma superclasse da qual todas as classes relacionadas ou similares são herdadas. Em outras palavras, uma classe abstrata contém todos os métodos / variáveis ​​compartilhados por todas as suas subclasses.

Marz
fonte
1

Na classe abstrata, você pode escrever a implementação padrão dos métodos! Mas na interface você não pode. Basicamente, na interface existem métodos virtuais puros que precisam ser implementados pela classe que implementa a interface.

dg_no_9
fonte
1

Sim, suas respostas foram tecnicamente corretas, mas onde você errou não estava mostrando a elas que entende as vantagens e desvantagens de escolher uma sobre a outra. Além disso, eles provavelmente estavam preocupados / assustados com a compatibilidade de sua base de código com atualizações no futuro. Esse tipo de resposta pode ter ajudado (além do que você disse):

"A escolha de uma classe abstrata em detrimento de uma classe de interface depende do que projetarmos o futuro do código.

As classes abstratas permitem melhor compatibilidade com a frente porque você pode continuar adicionando comportamento a uma classe abstrata no futuro sem quebrar o código existente -> isso não é possível com uma classe de interface.

Por outro lado, as Classes de interface são mais flexíveis que as Classes abstratas. Isso ocorre porque eles podem implementar várias interfaces . O problema é que o Java não tem várias heranças, portanto, usar classes abstratas não permitirá que você use nenhuma outra estrutura de hierarquia de classes ...

Portanto, no final, uma boa regra geral é: Prefira usar classes de interface quando não houver implementações padrão / existentes em sua base de código. E use Classes abstratas para preservar a compatibilidade, se você souber que atualizará sua classe no futuro. "

Boa sorte na sua próxima entrevista!

Jaxian
fonte
1

Vou tentar responder usando o cenário prático para mostrar a distinção entre os dois.

As interfaces são fornecidas com carga zero, ou seja, nenhum estado precisa ser mantido e, portanto, é a melhor opção para associar apenas um contrato (capacidade) a uma classe.

Por exemplo, digamos que eu tenha uma classe Task que execute alguma ação, agora, para executar uma tarefa em um thread separado, não preciso estender a classe Thread. A melhor opção é fazer com que o Task implemente a interface Runnable (ou seja, implemente o método run () ) e, em seguida, passe o objeto desta classe Task para uma instância Thread e chame seu método start ().

Agora você pode perguntar e se Runnable fosse uma classe abstrata?

Bem, tecnicamente isso era possível, mas, em termos de design, essa teria sido uma má escolha:

  • Runnable não possui um estado associado e nem 'oferece' nenhuma implementação padrão para o método run ()
  • Tarefa teria que estendê-lo, portanto, não poderia estender nenhuma outra classe
  • A tarefa não tem nada a oferecer como especialização à classe Runnable, tudo o que precisa é substituir o método run ()

Em outras palavras, a classe Task precisava de um recurso para ser executado em um encadeamento, o que foi alcançado implementando os versos da interface Runnable estendendo a classe Thread que o tornaria um encadeamento.

Simplesmente coloque-nos uma interface para definir uma capacidade (contrato), enquanto usa uma classe abstrata para definir a implementação esquelética (comum / parcial) dela.

Disclaimer: exemplo bobo a seguir, tente não julgar :-P

interface Forgiver {
    void forgive();
}

abstract class GodLike implements Forgiver {
    abstract void forget();
    final void forgive() {
        forget();
    }
}

Agora você tem a opção de ser semelhante a Deus, mas pode optar por ser apenas perdoador (ou seja, não semelhante a Deus) e fazer:

class HumanLike implements Forgiver {
    void forgive() {
       // forgive but remember    
    }
}

Ou você pode optar por ser semelhante a Deus e fazer:

class AngelLike extends GodLike {
    void forget() {
       // forget to forgive     
    }
}

O PS com a interface java 8 também pode ter métodos estáticos e padrão (implementação substituível) e, portanto, a diferença entre a interface preto e branco e a classe abstrata é ainda mais reduzida.

sactiw
fonte
1

Quase tudo parece já estar coberto aqui .. Adicionando apenas mais um ponto na implementação prática da abstractclasse:

abstractA palavra-chave também é usada, apenas impede que uma classe seja instanciada. Se você tem uma classe concreta que não deseja instanciar - faça abstract.

Lâmina
fonte
1

hmm agora as pessoas estão com uma abordagem prática da fome, você está certo, mas a maioria dos entrevistadores parece de acordo com as exigências atuais e deseja uma abordagem prática.

Depois de terminar sua resposta, você deve pular no exemplo:

Resumo:

por exemplo, temos a função salarial que possui algum parâmetro comum a todos os funcionários. então podemos ter uma classe abstrata chamada CTC com corpo de método parcialmente definido, que será estendido por todo tipo de funcionário e redefinido conforme seus valores extras. Para funcionalidade comum.

public abstract class CTC {

    public int salary(int hra, int da, int extra)
    {
        int total;
        total = hra+da+extra;
        //incentive for specific performing employee
        //total = hra+da+extra+incentive;
        return total;
    }
}

class Manger extends CTC
{
}


class CEO extends CTC
{
}

class Developer extends CTC
{   
}

Interface

A interface em java permite ter funcionalidade entre interfaces sem estender essa e você precisa ser claro com a implementação da assinatura da funcionalidade que deseja introduzir em seu aplicativo. forçará você a ter uma definição. Para diferentes funcionalidades.

public interface EmployeType {

    public String typeOfEmployee();
}

class ContarctOne implements EmployeType
{

    @Override
    public String typeOfEmployee() {
        return "contract";
    }

}

class PermanentOne implements EmployeType
{

    @Override
    public String typeOfEmployee() {
        return "permanent";
    }

}

você também pode ter essa atividade forçada com a classe abstrata por métodos definidos como um abstrato, agora uma classe que estende a classe abstrata ou uma abstrata até que substitua essa função abstrata.

RTA
fonte
1

Pelo que entendi e como me aproximo,

Interface é como uma especificação / contrato, qualquer classe que implemente uma classe de interface precisa implementar todos os métodos definidos na classe abstrata (exceto os métodos padrão (introduzidos no Java 8))

Enquanto eu defino um resumo da classe quando conheço a implementação necessária para alguns métodos da classe e alguns métodos ainda não sei qual será a implementação (podemos conhecer a assinatura da função, mas não a implementação). Eu faço isso para que, mais tarde, na parte do desenvolvimento, quando eu sei como esses métodos sejam implementados, eu possa apenas estender essa classe abstrata e implementar esses métodos.

Nota: Você não pode ter o corpo da função nos métodos de interface, a menos que o método seja estático ou padrão.

Akash Lodha
fonte
0

Acredito que o que o entrevistador estava tentando chegar provavelmente fosse a diferença entre interface e implementação.

A interface - não uma interface Java, mas a "interface" em termos mais gerais - para um módulo de código é, basicamente, o contrato feito com o código do cliente que usa a interface.

A implementação de um módulo de código é o código interno que faz o módulo funcionar. Freqüentemente, você pode implementar uma interface específica em mais de uma maneira diferente e até alterar a implementação sem que o código do cliente esteja ciente da alteração.

Uma interface Java deve ser usada apenas como interface no sentido genérico acima, para definir como a classe se comporta em benefício do código do cliente usando a classe, sem especificar nenhuma implementação. Assim, uma interface inclui assinaturas de métodos - os nomes, tipos de retorno e listas de argumentos - para métodos que devem ser chamados pelo código do cliente e, em princípio, deve ter bastante Javadoc para cada método que descreve o que esse método faz. O motivo mais convincente para o uso de uma interface é se você planeja ter várias implementações diferentes da interface, talvez selecionando uma implementação dependendo da configuração da implantação.

Uma classe abstrata Java, por outro lado, fornece uma implementação parcial da classe, em vez de ter o objetivo principal de especificar uma interface. Deve ser usado quando várias classes compartilham código, mas quando também é esperado que as subclasses forneçam parte da implementação. Isso permite que o código compartilhado apareça em apenas um lugar - a classe abstrata -, deixando claro que partes da implementação não estão presentes na classe abstrata e que devem ser fornecidas pelas subclasses.

Warren Dew
fonte
0

sua resposta está certa, mas o entrevistador precisa que você se diferencie de acordo com a perspectiva de engenharia de software e não com os detalhes de Java.

Palavras simples:

Uma interface é como a interface de uma loja, qualquer coisa que seja mostrada nela deve estar na loja; portanto, qualquer método na interface deve estar implementado na classe concreta. Agora, e se algumas classes compartilharem alguns métodos exatos e variarem em outras. Suponha que a Interface seja sobre uma loja que contenha duas coisas e que duas lojas contenham equipamentos esportivos, mas uma tenha roupas extras e a outra tenha sapatos extras. Então, o que você faz é criar uma classe abstrata para Sport que implemente o método Sports e deixe o outro método não implementado. A classe abstrata aqui significa que esta loja não existe, mas é a base para outras classes / lojas. Dessa forma, você está organizando o código, evitando erros de replicação, unificando o código e garantindo a reutilização por outra classe.

Mosab Shaheen
fonte