Quais são as diferenças entre classes abstratas, interfaces e quando usá-las


15

Recentemente, comecei a entender o OOP e agora estou no ponto em que quanto mais leio sobre as diferenças entre classes abstratas e interfaces, mais confuso fico. Até agora, nenhum dos dois pode ser instanciado. As interfaces são mais ou menos projetos estruturais que determinam o esqueleto e os resumos são diferentes ao poder implementar parcialmente o código.

Gostaria de aprender mais sobre isso através da minha situação específica. Aqui está um link para minha primeira pergunta, se você quiser um pouco mais de informações básicas: Qual é um bom modelo de design para minha nova classe?

Aqui estão duas classes que eu criei:

class Ad {
    $title;
    $description
    $price;

    function get_data($website){  }

    function validate_price(){  }
 }


class calendar_event {
    $title;
    $description

    $start_date;

    function get_data($website){ //guts }

    function validate_dates(){ //guts }
 }

Então, como você pode ver, essas classes são quase idênticas. Não é mostrado aqui, mas há outras funções, like get_zip(), save_to_database()que são comuns em minhas aulas. Também adicionei outras classes de carros e animais de estimação que possuem todos os métodos comuns e, claro, propriedades específicas para essas classes (quilometragem, peso, por exemplo).

Agora, violei o princípio DRY e estou gerenciando e alterando o mesmo código em vários arquivos. Pretendo ter mais aulas, como barcos, cavalos ou o que for.

Então é aqui que eu usaria uma interface ou uma classe abstrata? Pelo que entendi sobre classes abstratas, eu usaria uma superclasse como um modelo com todos os elementos comuns incorporados à classe abstrata e, em seguida, adicionaria apenas os itens especificamente necessários em futuras classes. Por exemplo:

abstract class content {
    $title;
    $description


    function get_data($website){  }

    function common_function2() { }
    function common_function3() { }
 }


class calendar_event extends content {

    $start_date;

    function validate_dates(){  }
 }

Ou eu usaria uma interface e, por serem tão semelhantes, criaria uma estrutura que cada uma das subclasses é forçada a usar por motivos de integridade e deixaria ao desenvolvedor final que criar essa classe o responsável por cada um dos detalhes até das funções comuns. Na minha opinião, é possível que algumas funções "comuns" precisem ser aprimoradas no futuro para atender às necessidades de sua classe específica.

Apesar de tudo isso acima, se você acredita que estou entendendo errado o que e o porquê das classes e interfaces abstratas, deixe uma resposta válida parar de pensar nessa direção e sugerir a maneira correta de avançar!

Obrigado!


Existem muitos bons exemplos online. Eu acho que este é um deles. javapapers.com/core-java/abstract-and-interface-core-java-2/…
Siva

Respostas:


26

Em termos leigos:

As interfaces são para tipos de relacionamentos "podem fazer / podem ser tratados como" .

Classes abstratas (e concretas) são para "é um" tipo de relacionamento.

Veja estes exemplos:

class Bird extends Animal implements Flight;
class Plane extends Vehicle implements Flight, AccountableAsset;
class Mosquito extends Animal implements Flight;
class Horse extends Animal;
class RaceHorse extends Horse implements AccountableAsset;
class Pegasus extends Horse implements Flight;

Bird, MosquitoE Horse são Animals . Eles estão relacionados. Eles herdam métodos comuns do Animal like eat(), metabolize() and reproduce(). Talvez eles substituam esses métodos, adicionando um pouco mais a eles, mas tiram vantagem do comportamento padrão implementado em Animal comometabolizeGlucose().

Planenão está relacionado a Bird, Mosquitoou Horse.

Flighté implementado por classes diferentes e não relacionadas, como Birde Plane.

AccountableAssettambém é implementado por classes diferentes e não relacionadas, como Planee RaceHorse.

Horse não implementa o Flight.

Como você pode ver, as classes (abstratas ou concretas) ajudam a criar hierarquias , permitindo a você herdar código dos níveis superiores aos inferiores da hierarquia. Em teoria, quanto mais baixo você está na hierarquia, mais especializado é o seu comportamento, mas não precisa se preocupar com muitas coisas que já foram resolvidas.

As interfaces , por outro lado, não criam hierarquia, mas podem ajudar a homogeneizar certos comportamentos entre hierarquias, para que você possa abstraí-los da hierarquia em determinados contextos.

Por exemplo, você pode ter um programa que soma o valor de um grupo AccountableAssetsindependentemente de serem RaceHorsesou não Planes.


Surpreendente. A interface fornece uma certa seção de funcionalidade que impõe can do/can be treated asonde as classes abstratas agem como fundamentais!
Abhiroj Panwar

13

Você pode deduzir a resposta logicamente, pois parece estar ciente das diferenças entre os dois.

As interfaces definem um contrato comum. Como uma interface chamada IAnimal, onde todos os animais compartilham funções como Eat (), Move (), Attack () etc. Enquanto todos compartilham as mesmas funções, todos ou a maioria deles têm uma maneira diferente (implementação) de alcançar isto.

As classes abstratas definem uma implementação comum e, opcionalmente, contratos comuns. Por exemplo, uma calculadora simples pode se qualificar como uma classe abstrata que implementa todos os operadores lógicos e bit a bit básicos e depois é estendida pelo ScientificCalculator, GraphicalCalculator e assim por diante.

Se você tiver uma implementação comum, encapsule a funcionalidade em uma classe abstrata para estender. Tenho quase 0 de experiência em PHP, mas não acho que você possa criar interfaces com campos não constantes. Se os campos forem comuns entre as classes de instância, você será forçado a usar uma classe Abstract, a menos que defina o acesso a eles por meio de getters e setters.

Além disso, parece não haver falta de resultados no Google.


3

Longa história curta. As classes abstratas são muito parecidas com as interfaces, pois ambas fornecem um modelo de quais métodos devem estar dentro da classe herdada, mas existem grandes diferenças: - As interfaces definem apenas nomes / tipos de métodos que precisam existir em uma classe herdada, enquanto estão ausentes. As classes podem ter o código padrão completo do método e apenas os detalhes podem precisar ser substituídos. - As interfaces não podem ter modificadores de acesso. - As interfaces não podem ter campos. - Classes não podem ter herança múltipla de classes, enquanto podem herdar várias interfaces. - Além disso, as classes fornecem uma estrutura hierárquica, de modo que apenas as classes derivadas de uma classe específica precisam seguir as diretrizes da classe abstrata: objeto-> objeto específico-> objeto muito específico. As interfaces, por outro lado, podem ser herdadas por qualquer pessoa em qualquer lugar.

Na minha opinião, as classes abstratas são mais comuns, pois podem fornecer a implementação padrão do código imediatamente, mas em projetos de larga escala nos quais você precisa padronizar determinadas classes, as interfaces podem ser úteis.

Espero que ajude, mas há muitas informações neste site, Leo


2
Classes cannot have multiple inheritance- Verdadeiro para linguagens como Java e C #, não verdadeiro para C ++.
9788 Robert

3

Primeiro, você deve entender que geralmente fornecerá uma interface e uma classe abstrata. A razão para isso, e a principal diferença entre os dois, é que eles permitem reutilizar códigos diferentes e resolver problemas diferentes.

As interfaces permitem reutilizar o código do cliente com diferentes implementações. Um cliente da sua classe get_data ($ website) não se importa com os itens $ title ou $ description. Ele só quer instruir seu conteúdo para carregar os dados. Se você tiver tipos diferentes de conteúdo, alguns dos quais precisam de uma descrição $ e outros que não, você pode fornecer uma classe ContentInterface que especifique apenas a assinatura das suas classes filho. Agora, o cliente pode ter vários conteúdos diferentes sem saber exatamente como eles funcionam. O princípio da substituição de Liskov é uma coisa boa de se ler sobre o estudo dessa idéia. Também gosto da escrita do tio Bob sobre o assunto. As interfaces são muito importantes para o teste de unidade, e a criação de interfaces é um bom hábito para aprender.

As classes abstratas permitem reutilizar detalhes comuns de implementação em um conjunto de classes que compartilham um ancestral comum. Na sua pergunta, você parece ter uma boa idéia de por que herdaria a implementação de uma classe abstrata. Ainda é perigoso depender das partes internas de uma classe base - é muito fácil violar o encapsulamento e criar filhos que dependem de detalhes específicos de implementação de uma classe base. O Template Method Pattern fornece um exemplo comum e íntegro de como usar classes base sem violar o encapsulamento.

Portanto, como espero ter mostrado, você frequentemente fornecerá interfaces para os clientes da sua hierarquia de classes, para que você possa alterar com segurança sua implementação sem afetar o código do cliente. Isso permite que o cliente grave testes de unidade usando objetos simulados que herdam sua interface. E você também fornecerá classes abstratas que permitem reutilizar a lógica comum ou aplicar semântica para as classes filho.


3

A diferença é sutil, mas clara. Interface é sobre comportamento polimórfico. A aula abstrata é sobre reutilização e comportamento polimórfico.

Se você deseja enfatizar a reutilização e o comportamento polimórfico, escolha a classe abstrata. Por exemplo, funcionários de tipos diferentes têm disposições diferentes, mas todos recebem alguns em comum. Portanto, a classe abstrata é adequada para representá-la porque as semelhanças podem ser expressas em uma classe abstrata de base Employeee a diferença pode ser implementada em classes derivadas como Managerou Workeretc.

Se você deseja enfatizar apenas o comportamento polimórfico, escolha interface. A interface é mais sobre contrato, ou seja, um objeto ou hierarquia dizendo que está de acordo com determinado comportamento. Por exemplo, todos os funcionários têm provisão para licença, mas diferentes tipos de funcionários têm tipos diferentes de provisões. Portanto, cada tipo diferente de funcionário exige uma calculadora de licença diferente. Aqui, a interface é uma boa opção, porque todos os tipos de funcionários podem implementar uma LeaveCalculatorinterface com um Calculate()comportamento diferente.


-3
  1. A principal diferença é que 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.
  2. As variáveis ​​declaradas em uma interface Java são, por padrão, finais. Uma classe abstrata pode conter variáveis ​​não finais.
  3. 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.
  4. A interface Java deve ser implementada usando a palavra-chave "implementa"; Uma classe abstrata de Java deve ser estendida usando a palavra-chave “extends”.
  5. Uma interface pode estender outra interface Java, apenas uma classe abstrata pode estender outra classe Java e implementar várias interfaces Java.
  6. Uma classe Java pode implementar várias interfaces, mas pode estender apenas uma classe abstrata.
  7. A interface é absolutamente abstrata e não pode ser instanciada; Uma classe abstrata Java também não pode ser instanciada, mas pode ser invocada se existir um main ().
  8. Em comparação com as classes abstratas java, as interfaces java são lentas, pois requerem indireção extra.
  9. A interface e a classe abstrata em Java é que você não pode criar um método não abstrato na interface, todo método na interface é abstrato por padrão, mas é possível criar um método não abstrato na classe abstrata.
  10. A classe abstrata versus a interface em Java é que, as interfaces são mais adequadas para a declaração Type e a classe abstrata é mais adequada para a reutilização de código e a perspectiva da evolução.
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.