Vídeo: Classes e Métodos Abstratos 2024
C ++ suporta ligação tardia , , que é quando resolve uma chamada de método com base no tempo de execução digite (ou tipo dinâmico) do objeto alvo em vez do tipo declarado (ou tipo estático). Isso é demonstrado no seguinte trecho de código C ++:
#incluir usando namespace std; classe Oven {public: virtual vide vaca () {cout << "cozinhando com um forno" << endl;}}; classe MicrowaveOven: public Oven {public: virtual void cook () {cout << "cooking with a microwave oven" << endl;}}; vazio prepareMeal (forno e forno) {forno. cook ();}
Na função prepareMeal (), a chamada ao forno. Cook () pode passar para Forno:: cook () ou MicrowaveOven:: cook () dependendo do tempo de execução (o "real") do tipo do objeto do forno passado.
A palavra-chave virtual é fundamental aqui. Sem ele, o método cook () seria vinculado com antecedência, com base no tipo de compilação e invocando o Forno:: cook () sempre. Uma vez declarada virtual na classe Horno, o método é assumido como virtual em cada subclasse, mas não faz mal para repetir a declaração para que os leitores entendam.
O seguinte programa simples demonstra esse princípio na prática:
int main () {Forno de forno; PrepareMeal (forno); MicrowaveOven mo; prepareMeal (mo); retornar 0;}
Neste programa, a chamada para cozinhar () gera duas saídas diferentes dependendo do tipo de forno:
Cozinhar com um forno Cozinhar com um forno de microondas
Não é sempre o caso, que um método na classe base pode ser definido. Considere o caso do Forno com mais cuidado. Há uma série de diferentes tipos de fornos - fornos convencionais, fornos de convecção e fornos de microondas -, mas pode-se argumentar que não existe um forno real que não pertence a uma dessas subclasses. Você pode dizer como os vários tipos de fornos executam a operação de cozinhar - isto é, o que um convencional: cozinheiro () e uma função Microondas:: cozinhar () deve ser definido. Provavelmente não é possível definir quais ações o Forno:: cook () deve executar.
Você não pode simplesmente deixar o Forno:: cook () não declarado em uma linguagem fortemente digitada como C ++. No entanto, você pode declarar um método, mas deixe sem implementar se nenhuma implementação existir. Um usa a seguinte sintaxe curiosa para fazê-lo:
class Oven {public: virtual void cook () = 0;};
Este código declara um método Forno:: cook () que está vinculado atrasado, mas não implementa o método. Na verdade, vai ainda mais dizendo que o método não será implementado. Em C ++, esse método é dito ser puro virtual . Os programadores C ++ também usam o termo preferido em muitos outros idiomas de computador fortemente digitados: resumo .A classe do Forno é dita ser abstrata.
Um resumo representa uma propriedade que você conhece a classe possui, mas não sabe como implementar inequivocamente na classe atual.
A classe é abstrata se contiver um ou mais métodos virtuais puros. O significado disso é que você não pode instanciar uma classe abstrata. Assim, o seguinte não é mais permitido:
int main () {Forno de forno; PrepareMeal (forno); return 0;}
O motivo para isso é bastante simples: se você criou um objeto do forno da classe e tentou invocar o forno. cozinhar (), o que o compilador deve fazer?
Em um nível mais filosófico, é bom dizer que existe um termo comum chamado Forno que descreve fornos convencionais e fornos de microondas e fornos de convecção. O termo Forno é um conceito usual porque liga as semelhanças em todas essas subclasses. Mas não há instância de um forno que não seja uma das subclasses do Forno.
Uma subclasse de uma classe abstrata é abstrata até que todos os métodos virtuais puros tenham sido substituídos por versões não-abstratas (isto é, concreto ). Assim, a classe MicrowaveOven no fragmento de código anterior não é abstrata - mesmo que o Forno fosse abstrato - porque ele substitui cook () com sua própria versão concreta.
Observe que não há nada de errado com a função prepareMeal () definida da seguinte forma:
void prepareMeal (Forno e forno) {forno. cook ();}
Mesmo que o argumento seja declarado um forno, ele só pode ser invocado com alguma subclasse de Forno, como MicrowaveOven ou ConventionalOven, para o qual cook () está definido.