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

14

Recentemente eu comecei a envolver minha cabeça em torno da POO, e agora estou a ponto de quanto mais eu leio sobre as diferenças entre classes abstratas e interfaces, mais confusa me torno. Até agora, nenhum dos dois pode ser instanciado. As interfaces são modelos mais ou menos estruturais que determinam o esqueleto e os resumos são diferentes, sendo possível implementar parcialmente o código.

Eu gostaria de aprender mais sobre isso através da minha situação específica. Aqui está um link para a minha primeira pergunta, se você gostaria de um pouco mais de informação de fundo: O que é um bom modelo de design para minha nova classe?

Aqui estão duas classes que 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 classes. Eu também adicionei outras classes Cars e Pets 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. Eu pretendo ter mais aulas como barcos, cavalos ou o que for.

Então, isso é onde eu usaria uma interface ou uma classe abstrata? Pelo que eu entendo sobre classes abstratas, eu usaria uma superclasse como um modelo com todos os elementos comuns construídos na classe abstrata, e então 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, criar uma estrutura que cada uma das subclasses é forçada a usar por razões de integridade, e deixar para o desenvolvedor final que cria essa classe para ser responsável por cada um dos detalhes até mesmo das funções comuns. meu pensamento é que algumas funções 'comuns' podem precisar ser ajustadas no futuro para as necessidades de sua classe específica.

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

Obrigado!

    
por user66662 04.11.2012 / 00:38
fonte

6 respostas

24

Em termos leigos:

Interfaces são para "pode fazer / pode ser tratado como" tipo de relacionamento.

As aulas abstratas (bem como concretas) são para "é um tipo de relação" .

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 , Mosquito e Horse são Animals . Eles estão relacionados. Eles herdam métodos comuns do Animal como eat(), metabolize() and reproduce() . Talvez eles substituam esses métodos, adicionando um pouco mais a eles, mas eles aproveitam o comportamento padrão implementado no Animal como metabolizeGlucose().

Plane não está relacionado a Bird , Mosquito ou Horse .

Flight é implementado por classes dissimilares e não relacionadas, como Bird e Plane .

AccountableAsset também é implementado por classes dissimilares e não relacionadas, como Plane e 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 para os níveis inferiores da hierarquia. Em teoria, quanto mais baixo você está na hierarquia, mais especializado é o seu comportamento, mas você não precisa se preocupar com muitas coisas que já são tratadas.

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

Por exemplo, você pode fazer um programa somar o valor de um grupo de AccountableAssets , independentemente de serem RaceHorses ou Planes .

    
por 04.11.2012 / 03:04
fonte
13

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

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

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

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

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

    
por 04.11.2012 / 02:09
fonte
3

longa história curta. As classes abstratas são muito parecidas com as interfaces, na medida em que ambas fornecem um modelo de quais métodos devem estar dentro da classe herdada, mas há grandes diferenças: - As interfaces só definem os nomes / tipos de métodos que precisam existir em uma classe herdada, enquanto as classes abs podem ter o código de método padrão completo e apenas os detalhes podem precisar ser cancelados. - Interfaces não podem ter modificadores de acesso. - Interfaces não podem ter campos. - As 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 para que apenas as classes derivadas de uma classe específica precisem seguir as diretrizes da classe abstrata: object- > specific object- > objeto muito específico. 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 grande escala, onde é necessário padronizar certas classes, as interfaces podem ser úteis.

Espero que ajude, mas há muita informação sobre isso online, Leo

    
por 04.11.2012 / 01:09
fonte
3

Primeiramente, você deve entender que muitas vezes você fornecerá uma interface e uma classe abstrata. A razão para isso, e a principal diferença entre os dois, é que eles permitem que você reutilize códigos diferentes e, assim, resolva problemas diferentes.

As interfaces permitem que você reutilize o código do cliente com diferentes implementações. Um cliente da classe get_data ($ website) não se preocupa com os itens $ title ou $ description. Só quer instruir o seu conteúdo para carregar os dados. Se você tem diferentes tipos de conteúdo, alguns dos quais precisam de uma descrição $, e outros que não, você poderia fornecer uma classe ContentInterface que apenas especifica a assinatura de suas classes filhas. Agora, o cliente pode ter qualquer número de conteúdos diferentes sem que todos saibam exatamente como funcionam. O Princípio de Substituição de Liskov é uma boa coisa para se ler para estudar essa ideia. Também gosto de escrever sobre o tio Bob sobre o tópico. Interfaces são muito importantes para testes unitários, e a criação de interfaces é um bom hábito para aprender.

Classes abstratas permitem que você reutilize detalhes comuns de implementação em um conjunto de classes que compartilham um ancestral comum. Na sua pergunta, você parece ter uma boa noção de por que herdaria a implementação de uma classe abstrata. Ainda é perigoso depender dos componentes internos de uma classe base - é muito fácil violar o encapsulamento e criar crianças que dependem de detalhes de implementação específicos de uma classe base. O Template Method Pattern fornece um exemplo comum e saudável de como usar classes básicas sem violar o encapsulamento.

Assim, como espero ter mostrado, muitas vezes você fornecerá interfaces para os clientes de 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 Mock Objects que herdam sua interface. E você também fornecerá classes abstratas que permitem a reutilização de lógica comum ou reforça a semântica das classes filhas.

    
por 04.11.2012 / 02:31
fonte
3

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

Se você quiser enfatizar o reuso e o comportamento polimórfico, escolha a classe abstrata. Por exemplo, empregados de tipos diferentes têm provisões diferentes, mas todos recebem alguns comuns. Portanto, a classe abstrata é adequada para representá-la, porque as semelhanças podem ser expressas em uma classe abstrata de base Employee e a diferença pode ser implementada em classes derivadas como Manager ou Worker etc.

Se você quiser enfatizar apenas o comportamento polimórfico, escolha interface. Interface é mais sobre contrato, ou seja, um objeto ou hierarquia dizendo que está em conformidade com determinado comportamento. Por exemplo, todos os funcionários têm licença, mas diferentes tipos de empregados têm diferentes tipos de provisões. Assim, cada tipo diferente de funcionário exige uma calculadora de licenças diferente. Aqui, a interface é uma boa escolha, porque todos os tipos de funcionários podem implementar uma interface LeaveCalculator com um comportamento Calculate() de maneira diferente.

    
por 04.11.2012 / 04:18
fonte
-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 final. Uma classe abstrata pode conter variáveis não finais.
  3. Os membros de uma interface Java são públicos por padrão. Uma classe abstrata Java pode ter os sabores usuais de membros da classe como private, protected, etc.
  4. A interface Java deve ser implementada usando a palavra-chave "implementos"; Uma classe abstrata 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 chamada se existir um main ().
  8. Em comparação com as classes abstratas de java, as interfaces de java são lentas, pois exigem uma indireção extra.
  9. Interface e classe abstrata em Java é que você não pode criar um método não abstrato na interface, todo método na interface é por padrão abstrato, mas você pode criar um método não abstrato na classe abstrata.
  10. A classe abstrata versus interface em Java é que as interfaces são mais adequadas para a declaração Type e a classe abstrata é mais adequada para reutilização de código e perspectiva de evolução.
por 06.02.2013 / 15:48
fonte