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!
fonte
Respostas:
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:
Bird
,Mosquito
EHorse
sãoAnimals
. Eles estão relacionados. Eles herdam métodos comuns do Animal likeeat(), 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().
Plane
não está relacionado aBird
,Mosquito
ouHorse
.Flight
é implementado por classes diferentes e não relacionadas, comoBird
ePlane
.AccountableAsset
também é implementado por classes diferentes e não relacionadas, comoPlane
eRaceHorse
.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
AccountableAssets
independentemente de seremRaceHorses
ou nãoPlanes
.fonte
can do/can be treated as
onde as classes abstratas agem como fundamentais!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.
fonte
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
fonte
Classes cannot have multiple inheritance
- Verdadeiro para linguagens como Java e C #, não verdadeiro para C ++.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.
fonte
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
Employee
e a diferença pode ser implementada em classes derivadas comoManager
ouWorker
etc.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
LeaveCalculator
interface com umCalculate()
comportamento diferente.fonte
fonte