Durante uma revisão de código hoje, um colega meu disse algo interessante:
prototype
só é útil quando você precisa de herança - e quando a herança é uma boa ideia ?
Pensei sobre isso e percebi que geralmente uso herança para contornar códigos mal projetados em primeiro lugar. O estilo OO moderno prefere composição a herança, mas não conheço nenhum idioma que tenha levado isso a sério e que realmente a imponha .
Existem linguagens de programação de uso geral com classes, objetos, métodos, interfaces e assim por diante, que não permitem a herança baseada em classe? (Se essa ideia não faz sentido, por que não?)
object-oriented
programming-languages
inheritance
Benjamin Hodgson
fonte
fonte
prototype
é útil para quando você possui métodos e propriedades públicos que devem ser compartilhados entre instâncias. Também é útil porque permite que você use corretamente oinstanceof
operador em JavaScript:if (foo instanceof Foo) { ...
.implements
palavra - chave e interfaces (em oposição à herança de estado e comportamento introduzido com o uso daextends
palavra-chave em classes contendo qualquer implementação).new
,this
Eprototype
são todos muito de um campo minado para uso comum IMO.Respostas:
Deixando de lado a questão da definição de programação orientada a objetos, a questão se torna uma das "existem linguagens que usam apenas composição e não possuem ferramentas para herança?"
A resposta para isso é simplesmente "sim". Além disso, não há como fazer a herança como alguém pensa nela. Um pode incorporado um objecto noutro objecto e a estender esse objecto. Da linguagem desorientada a objetos ( espelho do github ):
Você tem uma estrutura de pessoa que tem um Nome que é uma String. Tem uma função pública chamada Intro que retorna o nome. A estrutura Woman também tem uma função para Intro, que acessa o suporte incorporado nela. E assim, podemos cumprir as intenções de herança usando apenas composição.
Mais sobre isso pode ser visto em Tutoriais do GoLang: Herança e subclassificação no Go - ou em sua quase semelhança .
Então, sim, é possível ter uma linguagem OO sem herança, e uma existe.
Dentro de casa, isso é conhecido como incorporação e oferece às estruturas anexas a capacidade de acessar os campos e funções incorporados como se os tivessem também - mas não é uma subclasse. A filosofia de design pode ser encontrada nas Perguntas frequentes sobre Go: Por que não há herança de tipo?
fonte
typedef
estruct
no C ...Isso se parece muito com uma descrição do VBA - Visual Basic for Applications, incorporado no Microsoft Office e outros hosts habilitados para VBA (por exemplo, AutoCAD, Sage 300 ERP, etc.) ou mesmo VB6. O "A" de "Básico" significa "Para todos os fins" de qualquer maneira, então há a parte "de uso geral".
O VB6 / VBA possui classes (e, portanto, objetos), métodos e interfaces - você pode definir uma
ISomething
interface em um módulo de classe como este:E depois tem outra classe que faz isso:
Essa classe, expondo nenhum membro público, só poderia ser acessada por meio de sua
ISomething
interface - e poderia haver dezenas de implementações diferentesISomething
por aí, então o código OOP VBA é perfeitamente capaz de polimorfismo e é perfeitamente legal para uma determinada classe para implementar várias interfaces também.No entanto, o VB6 / VBA não permite a herança de classe ; portanto, você não pode herdar uma implementação de outro tipo, apenas sua interface. Agora, se isso é um acidente, uma falha de design, um golpe de gênio ou uma enorme e feia supervisão estão abertos a debate; não está claro se o VB6 / VBA leva isso a sério , mas definitivamente o aplica .
Se o Go não faz herança de classe e ainda assim é uma linguagem OOP , não vejo por que o VB6 / VBA também não poderia ser considerado uma linguagem OOP.
</PreemptiveResponseToVBAHatersThatWillSayItIsNotAnOOPLanguage>
fonte
Você pode fazer com que o compilador imponha herança seletiva por meio do uso de privado / protegido e pelo uso moderno das técnicas "PImpl" ou "Implementação Privada".
Muitas APIs expõem apenas os componentes que você deseja que um usuário herde e ocultam o restante em uma classe de implementação separada. Portanto, você pode escrever classes cujas interfaces públicas são, de fato, não herdáveis, apenas utilizáveis através da composição de objetos e aplicadas pelo compilador. Isso geralmente é uma boa prática, quando ele usa o compilador para reforçar a intenção do software.
Uma pesquisa rápida por funções-membro privadas em javascript mostra que existe um princípio semelhante, embora qualquer pessoa possa ver seu código se puder usá-lo: http://www.crockford.com/javascript/private.html
fonte