Existe uma maneira de criar uma classe abstrata na linguagem Swift, ou isso é uma limitação como Objective-C? Eu gostaria de criar uma classe abstrata comparável ao que Java define como uma classe abstrata.
140
Existe uma maneira de criar uma classe abstrata na linguagem Swift, ou isso é uma limitação como Objective-C? Eu gostaria de criar uma classe abstrata comparável ao que Java define como uma classe abstrata.
Respostas:
Não há classes abstratas no Swift (assim como Objective-C). Sua melhor aposta será usar um protocolo , que é como uma interface Java.
Com o Swift 2.0, você pode adicionar implementações de métodos e implementações de propriedades calculadas usando extensões de protocolo. Suas únicas restrições são que você não pode fornecer variáveis ou constantes de membros e não há despacho dinâmico .
Um exemplo dessa técnica seria:
Observe que isso está fornecendo recursos de "classe abstrata", mesmo para estruturas, mas as classes também podem implementar o mesmo protocolo.
Observe também que toda classe ou estrutura que implementa o protocolo Employee precisará declarar a propriedade annualSalary novamente.
Mais importante, observe que não há despacho dinâmico . Quando
logSalary
é chamado na instância que é armazenada comoSoftwareEngineer
chama a versão substituída do método. QuandologSalary
é chamado na instância após ser convertido em umEmployee
, ele chama a implementação original (não envia dinamicamente para a versão substituída, mesmo que a instância seja realmente aSoftware Engineer
.Para obter mais informações, consulte o excelente vídeo da WWDC sobre esse recurso: Criando aplicativos melhores com tipos de valor no Swift
fonte
protocol Animal { var property : Int { get set } }
. Você também pode deixar o set se você não quer que a propriedade de ter um setterfunc logSalary()
à declaração de protocolo do funcionário, o exemplo será impressooverridden
para as duas chamadas paralogSalary()
. Isso está no Swift 3.1. Assim, você obtém os benefícios do polimorfismo. O método correto é chamado nos dois casos.Observe que esta resposta está direcionada ao Swift 2.0 e superior
Você pode obter o mesmo comportamento com protocolos e extensões de protocolo.
Primeiro, você escreve um protocolo que atua como uma interface para todos os métodos que precisam ser implementados em todos os tipos que estejam em conformidade.
Em seguida, você pode adicionar um comportamento padrão a todos os tipos que estão em conformidade com ele
Agora você pode criar novos tipos implementando
Drivable
.Então, basicamente, você obtém:
Drivable
implementemspeed
Drivable
(accelerate
)Drivable
é garantido para não ser instanciado, pois é apenas um protocoloNa verdade, esse modelo se comporta muito mais como características, o que significa que você pode estar em conformidade com vários protocolos e assumir implementações padrão de qualquer um deles, enquanto que com uma superclasse abstrata, você está limitado a uma hierarquia de classes simples.
fonte
UICollectionViewDatasource
,. Gostaria de remover todo o clichê e encapsular em protocolo / extensão separados e depois reutilizá-lo por várias classes. Na verdade, o padrão modelo seria perfeito aqui, mas ...Eu acho que este é o mais próximo de Java
abstract
ou C #abstract
:Observe que, para que os
private
modificadores funcionem, você deve definir esta classe em um arquivo Swift separado.EDIT: Ainda assim, este código não permite declarar um método abstrato e, portanto, força sua implementação.
fonte
A maneira mais simples é usar uma chamada para
fatalError("Not Implemented")
o método abstrato (não variável) na extensão do protocolo.fonte
(MyConcreteClass() as MyInterface).myMethod()
mas funciona! A chave está incluídamyMethod
na declaração do protocolo; caso contrário, a chamada trava.Depois de lutar por várias semanas, finalmente percebi como traduzir uma classe abstrata Java / PHP para Swift:
No entanto, acho que a Apple não implementou classes abstratas porque geralmente usa o padrão delegate + protocol. Por exemplo, o mesmo padrão acima seria melhor assim:
Eu precisava desse tipo de padrão porque queria comumizar alguns métodos no UITableViewController, como viewWillAppear etc. Isso foi útil?
fonte
Existe uma maneira de simular classes abstratas usando Protocolos. Isto é um exemplo:
fonte
Mais uma maneira de implementar a classe abstrata é bloquear o inicializador. Eu fiz dessa maneira:
fonte
Eu estava tentando criar uma
Weather
classe abstrata, mas o uso de protocolos não era o ideal, pois tive que escrever os mesmosinit
métodos repetidamente. Estender o protocolo e escrever uminit
método teve seus problemas, principalmente porque eu estava usando aNSObject
conformidadeNSCoding
.Então, eu vim com isso para a
NSCoding
conformidade:Quanto a
init
:fonte
Mova todas as referências para propriedades abstratas e métodos da classe Base para implementação de extensão de protocolo, em que Auto-restrição para a classe Base. Você terá acesso a todos os métodos e propriedades da classe Base. Adicionalmente, o compilador verifica a implementação de métodos e propriedades abstratas no protocolo para classes derivadas
fonte
Com a limitação de nenhum despacho dinâmico, você pode fazer algo assim:
fonte