Recientemente comencé a mirar el desarrollo de Android. Esto me ha traído de vuelta al mundo del desarrollo de software Java. La última vez que trabajé con Java, lo admito, no entendía OOP tanto como (creo) ahora.
Habiendo usado principalmente C # en mi carrera, noto una sorprendente diferencia en cómo se usa la herencia Java y C #.
En C # parecía que la herencia podría evitarse en la mayoría de las situaciones. La tarea en cuestión generalmente se puede lograr mediante el uso de clases concretas de .NET Framework.
En Java, por lo que estoy recopilando de muestras de código, parece que el marco de Java proporciona muchas interfaces o clases abstractas que el desarrollador debe implementar / extender.
Esto parece ser una gran diferencia para reducirlo al estilo. ¿Cuál es el razonamiento detrás de esto? Siento que no escribiré código Java limpio hasta que entienda esto.
Además, ¿esto se limita solo al SDK de Android o es un enfoque de Java para OOP?
O dicho de otra manera,
¿Qué tiene el diseño de estos dos idiomas que (parece alentar) más o menos el uso de la herencia que el otro?
Si los idiomas tratan la herencia de forma idéntica, y suponiendo que mi observación sea válida, significa que esto está relacionado con el diseño de los marcos / bibliotecas y no con los idiomas. ¿Cuál sería la motivación para este tipo de diseño?
fuente
Respuestas:
Tengo entendido que en gran medida es simplemente una decisión estilística. Bueno, quizás no sea el estilo, sino los modismos del lenguaje / entorno. Los desarrolladores de la biblioteca estándar de Java siguieron un conjunto de pautas de diseño y los desarrolladores de .NET otro (aunque tenían la capacidad de ver cómo funcionaba el enfoque de Java).
Hay muy poco en los idiomas actuales para alentar o disuadir la herencia. Solo dos cosas me parecen relevantes:
.NET introdujo genéricos más temprano en su vida, antes de que se implementara demasiado código no genérico. La alternativa es mucha herencia para escribir cosas especializadas.
Un cambio mayor fue que .NET apoyó delegados. En Java, está atascado con la herencia (anónima) para proporcionar la funcionalidad variable más básica. Esto conduce a una diferencia relativamente grande en la forma en que el código está diseñado para aprovechar delegados o para evitar las estructuras de herencia incómodas necesarias para hacerlo en Java.
fuente
Estos son idiomas muy diferentes, particularmente en esta área. Digamos que tienes una clase. En este caso, lo haremos un control de usuario, algo así como un cuadro de texto. Llámalo UIControl. Ahora queremos poner esto en otra clase. En este caso, como estamos usando una IU para nuestro ejemplo, la llamaremos la clase CleverPanel. Nuestra instancia de CleverPanel querrá saber sobre las cosas que le suceden a su instancia de UIControl por varias razones. ¿Como hacer esto?
En C #, el enfoque básico es verificar varios eventos, configurando métodos que se ejecutarán cuando se active cada evento interesante. En Java, que carece de eventos, la solución habitual es pasar un objeto con varios métodos de manejo de "eventos" a un método UIControl:
Hasta ahora, la diferencia entre C # y Java no es profunda. Sin embargo, tenemos la interfaz DoSomething que no se necesita en C #. Además, esta interfaz puede incluir muchos métodos que no son necesarios la mayor parte del tiempo. En C #, simplemente no manejamos ese evento. En Java, creamos una clase que proporciona una implementación nula para todos los métodos de interfaz, DoSomethingAdapter. Ahora reemplazamos DoSomething con DoSomethingAdapter y no necesitamos escribir ningún método para una compilación limpia. Terminamos anulando los métodos que necesitamos para que el programa funcione correctamente. Así que terminamos necesitando una interfaz y usando herencia en Java para que coincida con lo que hicimos con los eventos en C #.
Este es un ejemplo, no una discusión exhaustiva, pero brinda los conceptos básicos de por qué hay tanta herencia en Java en comparación con C #.
Ahora, ¿por qué Java funciona de esta manera? Flexibilidad. El objeto pasado a whenSomethingHappens podría haberse pasado completamente a CleverPanel desde otro lugar. Podría ser algo que varias instancias de CleverPanel deberían pasar a sus objetos similares a UIControl para ayudar a un objeto CleverWindow en alguna parte. O el UIControl podría pasarlo a uno de sus componentes.
Además, en lugar de un adaptador, puede haber una implementación DoSomething en algún lugar que tenga miles de líneas de código detrás. Podríamos crear una nueva instancia de eso y pasarlo. Es posible que debamos anular un método. Un truco común en Java es tener una clase grande con un método como:
Luego en CleverlPanel:
La plataforma Java de código abierto hace mucho de esto, lo que tiende a impulsar a los programadores a hacer más, tanto porque lo siguen como un ejemplo y simplemente para usarlo. Creo que el diseño básico del lenguaje está detrás del diseño del marco de Sun y detrás del programador de Java que usa las técnicas cuando no usa el marco.
Es realmente fácil crear una clase sobre la marcha en Java. La clase, anónima o con nombre, solo necesita ser referenciada en un pequeño bloque de código enterrado profundamente en un método. Se puede crear completamente nuevo o mediante ligeras modificaciones a una clase existente muy grande. (Y la clase existente puede ser de nivel superior en su propio archivo, o anidada en una clase de nivel superior, o definida solo dentro de un solo bloque de código). La nueva instancia de clase puede tener acceso completo a todos los datos del objeto de creación. Y la nueva instancia se puede pasar y usar en todo el programa, representando el objeto que la creó.
(Por otro lado, tenga en cuenta que un gran uso de la herencia aquí, como en otros lugares de Java, es simplemente para fines SECOS. Permite que diferentes clases reutilicen el mismo código. Tenga en cuenta también la facilidad de herencia en Java que fomenta esto. )
Nuevamente, esta no es una discusión exhaustiva; Solo estoy rascando la superficie aquí. Pero sí, hay una sorprendente diferencia en cómo se usa la herencia entre Java y C #. Son, a este respecto, idiomas muy diferentes. No es tu imaginación.
fuente
No hay absolutamente ninguna diferencia en la forma en que se maneja la herencia entre Java y C #. Cuando realmente usará la herencia o la composición es definitivamente una decisión de diseño y de ninguna manera es algo que Java o C # alienta o desalienta. Sugeriría amablemente leer este artículo .
Espero haber ayudado!
fuente