Durante una revisión de código hoy, un colega mío dijo algo interesante:
prototype
solo es útil cuando necesita herencia, y ¿ cuándo es una buena idea la herencia ?
Pensé en esto y me di cuenta de que generalmente uso la herencia para evitar el código mal diseñado en primer lugar. El estilo OO moderno prefiere la composición sobre la herencia, pero no conozco ningún idioma que haya tomado esto en serio y realmente lo imponga .
¿Hay algún lenguaje de programación de propósito general con clases, objetos, métodos, interfaces, etc., que no permita la herencia basada en clases? (Si tal idea no tiene sentido, ¿por qué no?)
object-oriented
programming-languages
inheritance
Benjamin Hodgson
fuente
fuente
prototype
también es útil para cuando tiene métodos públicos y propiedades que deben compartirse entre instancias. También es útil porque permite utilizar adecuadamente elinstanceof
operador en JavaScript:if (foo instanceof Foo) { ...
.implements
palabra clave y las interfaces (en oposición a la herencia de estado y comportamiento introducido con el uso de laextends
palabra clave en clases que contienen cualquier implementación).new
,this
yprototype
son demasiado de un campo de minas para uso común IMO.Respuestas:
Dejando a un lado la cuestión de la definición de programación orientada a objetos, la pregunta se convierte en una de "¿existen lenguajes que usan solo composición y no tienen herramientas para la herencia?"
La respuesta a esto es simplemente "sí". En el camino, no hay forma de hacer la herencia como se piensa clásicamente. Uno puede incrustar un objeto en otro objeto y extender ese objeto. Del lenguaje desorientado de objetos ( espejo github ):
Tienes una estructura de persona que tiene un Nombre que es una Cadena. Tiene una función pública llamada Introducción que devuelve el nombre. La estructura Woman también tiene una función para Intro que accede al puntal incrustado en ella. Y entonces uno puede cumplir las intenciones de la herencia usando solo la composición.
Se puede ver más sobre esto en los Tutoriales de GoLang: Herencia y subclases en Go, o su parecido cercano .
Entonces, sí, es posible tener un lenguaje OO sin herencia, y existe uno.
Dentro de ir, esto se conoce como incrustación y le da a las estructuras envolventes la capacidad de acceder a los campos incrustados y funciona como si también los tuviera, pero no es una subclase. La filosofía de diseño se puede encontrar en las Preguntas frecuentes de Go: ¿Por qué no hay herencia de tipo?
fuente
typedef
ystruct
en C ...Esto se parece mucho a una descripción de VBA: Visual Basic para aplicaciones, integrado en Microsoft Office y otros hosts habilitados para VBA (por ejemplo, AutoCAD, Sage 300 ERP, etc.), o incluso VB6. La "A" de "Básico" significa "Uso múltiple" de todos modos, por lo que está la parte "uso general".
VB6 / VBA tiene clases (y, por lo tanto, objetos), métodos e interfaces; podría definir una
ISomething
interfaz en un módulo de clase como este:Y luego tenga otra clase que haga esto:
A tal clase, sin exponer a ningún miembro público, solo se podía acceder a través de su
ISomething
interfaz, y podría haber docenas de implementaciones diferentesISomething
, por lo que el código OOP VBA es perfectamente capaz de polimorfismo, y es perfectamente legal para una clase determinada. para implementar múltiples interfaces, también.Sin embargo, VB6 / VBA no permite la herencia de clases , por lo que no puede heredar una implementación de otro tipo, solo su interfaz. Ahora, si esto es un accidente, un defecto de diseño, un golpe de genio o una gran supervisión fea está abierto a debate; no está claro si VB6 / VBA se toma esto en serio , pero definitivamente lo hace cumplir .
Si Go no hace herencia de clases y, sin embargo, es un lenguaje OOP , entonces no veo por qué VB6 / VBA no podría considerarse también un lenguaje OOP.
</PreemptiveResponseToVBAHatersThatWillSayItIsNotAnOOPLanguage>
fuente
Puede hacer que el compilador imponga la herencia selectiva mediante el uso de técnicas privadas / protegidas, y mediante el uso moderno de técnicas "PImpl" o "Implementación privada".
Muchas API exponen solo aquellos componentes que desea que un usuario herede, y ocultan el resto en una clase de implementación separada. Por lo tanto, podría escribir clases cuyas interfaces públicas sean, de hecho, no heredables, solo utilizables a través de la composición de objetos y forzadas por el compilador. Esto suele ser una buena práctica, cuando utiliza el compilador para hacer cumplir la intención del software.
Una búsqueda rápida de funciones para miembros privados en JavaScript muestra que hay un principio similar, aunque cualquiera puede ver su código si puede usarlo: http://www.crockford.com/javascript/private.html
fuente