De acordo com Herb Sutter, deve-se preferir interfaces abstratas (todas as funções virtuais puras) a abstrair classes em C ++ para dissociar a implementação o máximo possível. Embora eu pessoalmente ache essa regra muito útil, ingressei recentemente em uma equipe com muitos programadores Java e, no código Java, essa diretriz parece não existir. Funções e suas implementações são frequentemente localizadas em classes abstratas. Então, eu errei o Herb Sutter, mesmo em C ++, ou existe uma diferença geral no uso de funções abstratas em C ++ em comparação com Java. As classes abstratas com código de implementação são mais sensíveis em Java do que em C ++ e, se sim, por quê?
java
c++
interfaces
abstract-class
Martin
fonte
fonte
Respostas:
OOP tem composição e substituição.
O C ++ possui herança múltipla, especialização de modelo, incorporação e semântica de valor / movimentação / ponteiro.
Java possui herança e interfaces únicas, semântica de incorporação e referência.
A maneira comum de a escola OOP usar esses idiomas é empregar herança para substituição de objetos e incorporação para composição. Mas você também precisa de um ancestral comum e de uma maneira de converter o tempo de execução (em C ++ é chamado
dynamic_cast
, em Java é apenas pedir uma interface a outra).Java faz tudo isso por sua própria
java.lang.Object
hierarquia enraizada. O C ++ não possui uma raiz comum predefinida, portanto, você deve pelo menos defini-la, para obter a mesma "imagem" (mas isso está limitando algumas possibilidades do C ++ ...).Depois disso, a possibilidade de ter polimorfismo em tempo de compilação (pense no CRTP) e semântica de valor também pode oferecer outras alternativas à maneira como o conceito de "objeto OOP" pode ser portado para um programa C ++.
Você pode até imaginar a heresia de usar a incorporação e a conversão implícita para gerenciar a substituição e a herança privada para gerenciar a composição, de fato invertendo o paradigma tradicional da escola. (É claro que, dessa maneira, é 20 anos mais novo que o outro, por isso não espere um amplo apoio da comunidade para fazer isso)
Ou você pode imaginar uma base comum virtual para todas as classes, interface de formulário (sem implementação) para classes finais (totalmente implementada) passando por interfaces parcialmente implementadas e até clusters de interface, usando "dominância" como despacho da interface para implementações através de um "multi-stacked" -parallelogram "esquema de herança.
Comparar OOP com java e C ++, assumindo que há apenas uma e única maneira de OOP está limitando os recursos de ambos os idiomas.
Forçar o C ++ a aderir estritamente aos idiomas de codificação Java está desnaturando o C ++, como forçar o Java a se comportar como uma linguagem semelhante ao C ++ está desnaturando o Java.
Não é uma questão de "sensibilidade", mas de diferentes "mecanismos de agregação" que as duas línguas têm e uma maneira diferente de combiná-las, o que torna um idioma mais lucrativo em um idioma que o outro e vice-versa.
fonte
O princípio vale para os dois idiomas, mas você não está fazendo uma comparação justa. Você deve comparar as classes abstratas puras do C ++ com as interfaces Java.
Mesmo em C ++, você pode ter classes abstratas que possuem algumas das funções implementadas, mas derivam de uma classe abstrata pura (sem implementações). Em Java, você teria as mesmas classes abstratas (com algumas implementações), que podem derivar de interfaces (sem implementações).
fonte
Geralmente, os mesmos princípios de OO são verdadeiros para Java e C ++. No entanto, uma grande diferença é que o C ++ suporta herança múltipla enquanto em Java você pode herdar apenas de uma classe. Essa é a principal razão pela qual o Java possui interfaces, acredito, para complementar a falta de herança múltipla e provavelmente restringir o que você pode fazer com ela (já que há muitas críticas sobre o abuso de herança múltipla). Portanto, provavelmente na mente de programadores Java, há uma distinção mais forte entre classes abstratas e interfaces. Classes abstratas são usadas para compartilhar e herdar comportamento, enquanto as interfaces são simplesmente usadas para adicionar funcionalidade extra. Lembre-se, em Java, você pode herdar de apenas uma classe, mas pode ter muitas interfaces. No C ++, no entanto, as classes abstratas puras (ou seja, uma "interface C ++") são usado para compartilhar e herdar comportamento, diferentemente do objetivo de uma interface Java (embora você ainda precise implementar as funções), portanto, o uso é diferente das interfaces Java.
fonte
Às vezes, faz sentido ter alguma implementação padrão. Por exemplo, um método genérico PrintError (string msg) aplicável a todas as subclasses.
Ele ainda pode ser substituído, se realmente necessário, mas você pode economizar um pouco de trabalho ao cliente, permitindo que ele chame apenas a versão genérica.
fonte