O que você verá às vezes é o seguinte:
class Abstract1( object ):
"""Some description that tells you it's abstract,
often listing the methods you're expected to supply."""
def aMethod( self ):
raise NotImplementedError( "Should have implemented this" )
Como o Python não possui (e não precisa) um contrato formal de interface, a distinção no estilo Java entre abstração e interface não existe. Se alguém se esforçar para definir uma interface formal, também será uma classe abstrata. As únicas diferenças estariam na intenção declarada na doutrina.
E a diferença entre abstrato e interface é uma coisa complicada quando você digita pato.
Java usa interfaces porque não possui herança múltipla.
Como o Python tem herança múltipla, você também pode ver algo assim
class SomeAbstraction( object ):
pass # lots of stuff - but missing something
class Mixin1( object ):
def something( self ):
pass # one implementation
class Mixin2( object ):
def something( self ):
pass # another
class Concrete1( SomeAbstraction, Mixin1 ):
pass
class Concrete2( SomeAbstraction, Mixin2 ):
pass
Isso usa um tipo de superclasse abstrata com mixins para criar subclasses de concreto disjuntas.
NotImplementedError("Class %s doesn't implement aMethod()" % (self.__class__.__name__))
é a mensagem de erro mais informativa :)Uma interface, para um objeto, é um conjunto de métodos e atributos nesse objeto.
No Python, podemos usar uma classe base abstrata para definir e aplicar uma interface.
Usando uma classe base abstrata
Por exemplo, digamos que desejemos usar uma das classes base abstratas do
collections
módulo:Se tentarmos usá-lo, obtemos um
TypeError
porque a classe que criamos não suporta o comportamento esperado dos conjuntos:Assim, somos obrigados a implementar pelo menos
__contains__
,__iter__
e__len__
. Vamos usar este exemplo de implementação da documentação :Implementação: Criando uma classe base abstrata
Podemos criar nossa própria classe base abstrata, definindo a metaclasse
abc.ABCMeta
e usando oabc.abstractmethod
decorador nos métodos relevantes. A metaclasse adicionará as funções decoradas ao__abstractmethods__
atributo, impedindo a instanciação até que sejam definidas.Por exemplo, "efável" é definido como algo que pode ser expresso em palavras. Digamos que desejamos definir uma classe base abstrata que seja eficaz, no Python 2:
Ou no Python 3, com a pequena alteração na declaração de metaclasse:
Agora, se tentarmos criar um objeto eficaz sem implementar a interface:
e tente instancia-lo:
Dizem-nos que não terminamos o trabalho.
Agora, se cumprirmos, fornecendo a interface esperada:
então podemos usar a versão concreta da classe derivada da abstrata:
Há outras coisas que poderíamos fazer com isso, como registrar subclasses virtuais que já implementam essas interfaces, mas acho que isso está além do escopo desta questão. Os outros métodos demonstrados aqui teriam que adaptar esse método usando o
abc
módulo para fazê-lo, no entanto.Conclusão
Demonstramos que a criação de uma classe base abstrata define interfaces para objetos personalizados em Python.
fonte
Python> = 2.6 possui classes base abstratas .
Há também o módulo Zope Interface , que é usado por projetos fora do zope, como twisted. Eu não estou realmente familiarizado com isso, mas há uma página wiki aqui que pode ajudar.
Em geral, você não precisa do conceito de classes abstratas ou interfaces em python (editado - consulte a resposta de S.Lott para obter detalhes).
fonte
Python realmente não tem nenhum conceito.
Ele usa digitação de pato, o que eliminou a necessidade de interfaces (pelo menos para o computador :-))
Python <= 2.5: As classes base obviamente existem, mas não há uma maneira explícita de marcar um método como 'virtual puro'; portanto, a classe não é realmente abstrata.
Python> = 2.6: As classes base abstratas existem ( http://docs.python.org/library/abc.html ). E permita que você especifique métodos que devem ser implementados nas subclasses. Não gosto muito da sintaxe, mas o recurso está lá. Na maioria das vezes, provavelmente é melhor usar a digitação de pato no lado do cliente 'using'.
fonte
De uma maneira mais básica para explicar: Uma interface é como uma forma vazia de muffin. É um arquivo de classe com um conjunto de definições de métodos que não têm código.
Uma classe abstrata é a mesma coisa, mas nem todas as funções precisam estar vazias. Alguns podem ter código. Não é estritamente vazio.
Por que diferenciar: Não há muita diferença prática no Python, mas no nível de planejamento de um projeto grande, pode ser mais comum falar sobre interfaces, pois não há código. Especialmente se você estiver trabalhando com programadores Java acostumados ao termo.
fonte
Em geral, as interfaces são usadas apenas em idiomas que usam o modelo de classe de herança única. Nessas linguagens de herança única, as interfaces são normalmente usadas se alguma classe puder usar um método ou conjunto de métodos específico. Também nessas linguagens de herança única, as classes abstratas são usadas para ter variáveis de classe definidas, além de nenhum ou mais métodos, ou para explorar o modelo de herança única para limitar o intervalo de classes que poderia usar um conjunto de métodos.
Os idiomas que suportam o modelo de herança múltipla tendem a usar apenas classes ou classes base abstratas e não interfaces. Como o Python suporta herança múltipla, ele não usa interfaces e você deseja usar classes base ou classes base abstratas.
http://docs.python.org/library/abc.html
fonte
Classes abstratas são classes que contêm um ou mais métodos abstratos. Juntamente com os métodos abstratos, as classes Abstratas podem ter métodos estáticos, de classe e de instância. Mas no caso da interface, ela só terá métodos abstratos e não outros. Portanto, não é obrigatório herdar a classe abstrata, mas é obrigatório herdar a interface.
fonte
Por questões de integridade, devemos mencionar o PEP3119, onde o ABC foi introduzido e comparado com interfaces, e os originais de Talin. comentário .
A classe abstrata não é uma interface perfeita:
Mas se você pensar em escrever à sua maneira:
você perceberá rapidamente que está inventando a roda para finalmente alcançar
abc.ABCMeta
abc.ABCMeta
foi proposto como uma adição útil da funcionalidade de interface ausente, e isso é justo o suficiente em uma linguagem como python.Certamente, ele foi aprimorado melhor enquanto escrevia a versão 3 e adicionava nova sintaxe e conceito de interface imutável ...
Conclusão:
fonte