what usan unity tipos sintaxis qué por poo polimorfismo poliformismo parametrico metodos las interfaz interfaces implement herency herencia genético form encapsulamiento ejercicios ejemplos create como codigo clases clase caracteristicas biología and abstractas c# .net oop interface polymorphism

c# - usan - tipos de polimorfismo



Son interfaces compatibles con el polimorfismo (4)

Estoy teniendo problemas con el concepto de interfaces que interactúan con tipos polimórficos (o incluso interfaces polimórficas). Me estoy desarrollando en C # y agradecería que las respuestas se mantuvieran cerca de esta definición, aunque creo que eso todavía deja mucho espacio para que todos puedan responder.

Solo como ejemplo, digamos que quieres hacer un programa para pintar cosas. Usted define una interfaz para el actor que pinta, y define una interfaz para el tema que se pinta. Además, tiene algunos temas que se pueden pintar de una manera más específica.

interface IPainter { void paint(IPaintable paintable); } interface IPaintable { void ApplyBaseLayer(Color c); } interface IDecalPaintable : IPaintable { void ApplyDecal(HatchBrush b); }

Me imagino haciendo un pintor similar al siguiente:

class AwesomeDecalPainter : IPainter { public void paint(IPaintable paintable) { IDecalPaintable decalPaintable = (IDecalPaintable)paintable; decalPaintable.ApplyBaseLayer(Color.Red); decalPaintable.ApplyDecal(new HatchBrush(HatchStyle.Plaid, Color.Green)); } }

Por supuesto, esto se lanzará si Paintable no implementa IDecalPaintable. Inmediatamente introduce un acoplamiento entre la implementación de IPainter y el IPaintable en el que opera. Sin embargo, tampoco creo que tenga sentido decir que AwesomeDecalPainter no es un IPainter solo porque su uso está limitado a un subconjunto del dominio IPaintable.

Así que mi pregunta es realmente cuádruple:

  • ¿La interfaz es compatible con el polimorfismo?
  • ¿Es un buen diseño implementar un IPainter que pueda operar en IDecalPaintable?
  • ¿Qué pasa si puede operar exclusivamente en IDecalPaintable?
  • ¿Existe alguna literatura o código fuente que ejemplifique cómo deben interactuar las interfaces y los tipos polimórficos?

¿Estoy entendiendo tu pregunta correctamente?

Creo que tu pregunta es si la interfaz puede ejercer lo esencial de la herencia.

(es decir, la interfaz secundaria que se hereda de la interfaz principal).

1) Si ese es el caso, sintácticamente seguro, ¿por qué no?

2) en cuanto a la practicabilidad, puede ser de poco valor porque sus interfaces secundarias no están esencialmente reutilizando nada de su interfaz principal.


El problema realmente es que usted ha definido una interfaz vaga, un contrato es un término más apropiado. Es como entrar en McDonalds y pedir una hamburguesa:

interface Resturant { Burger BuyBurger(); }

La persona que toma su pedido se verá un poco confundida por un tiempo, pero eventualmente le servirá cualquier hamburguesa ya que no especifica lo que desea.

Lo mismo aqui. ¿Realmente solo quieres definir que algo es pintable? Si me preguntas, es como pedir problemas. Siempre trate de hacer las interfaces lo más específicas posible. Siempre es mejor tener varias interfaces específicas pequeñas que una general grande.

Pero volvamos a tu ejemplo. En tu caso, todas las clases solo tienen que ser capaces de pintar algo. Por eso añadiría otra interfaz más específica:

interface IPainter { void Paint(IPaintable paintable); } interface IDecalPainter : IPainter { void Paint(IDecalPaintable paintable); } interface IPaintable { void ApplyBaseLayer(Color c); } interface IDecalPaintable : IPaintable { void ApplyDecal(HatchBrush b); } class AwesomeDecalPainter : IDecalPainter { public void Paint(IPaintable paintable) { IDecalPaintable decalPaintable = paintable as IDecalPaintable; if (decalPaintable != null) Paint(decalPaintable); else paintable.ApplyBaseLayer(Color.Red); } public void Paint(IDecalPaintable paintable) { paintable.ApplyBaseLayer(Color.Red); paintable.ApplyDecal(new HatchBrush(HatchStyle.Plaid, Color.Green)); } }

Te recomendaría que leas sobre los principios de SOLID.

Actualizar

Una implementación de interfaz más sólida.

interface IPaintingContext { //Should not be object. But my System.Drawing knowledge is limited object DrawingSurface { get; set; } } interface IPaintable { void Draw(IPaintingContext context); } class AwesomeDecal : IPaintable { public void Draw(IPaintingContext paintable) { // draw decal } } class ComplexPaintableObject : IPaintable { public ComplexPaintableObject(IEnumerable<IPaintable> paintable) { // add background, border } }

Aquí puede crear elementos de pintura tan complejos como sea posible. Ahora saben qué pintan, o qué otras tablas de pintar se usan en la misma superficie.


La interfaz de una clase es una herramienta para el "usuario" de esa clase. Una interfaz es una presentación pública para la clase, y debe anunciar, a cualquiera que esté considerando usarla, qué métodos y constantes están disponibles y son accesibles desde el exterior. Entonces, como su nombre lo indica, siempre se encuentra entre el usuario y la clase que lo implementa.

Por otro lado, una clase abstracta es una herramienta destinada a ayudar al "implementador" de las clases que la extienden. Es una infraestructura que puede imponer restricciones y pautas sobre cómo deberían ser las clases concretas. Desde una perspectiva de diseño de clase, las clases abstractas son más importantes desde el punto de vista arquitectónico que las interfaces. En este caso, el implementador se sienta entre la clase abstracta y la concreta, construyendo la última sobre la primera.

Entonces, para responder a su pregunta simplemente, Interface es un "contrato" para que el código lo respete. Cuando se usa de esta manera, se aplica más a la herencia que el polimorfismo.

Clases abstractas, definen un ''tipo''. Y cuando las subclases concretas usan clases abstractas y redefinen métodos, agregan nuevos, etc ... ahí se ve el polimorfismo en acción.

Sé que esta publicación puede confundirte más, no tenía sentido para mí hasta que aprendí patrones de diseño. Con unos pocos patrones simples en su haber, comprenderá mejor el papel de cada objeto y cómo la herencia, el polimorfismo y la encapsulación juegan mano a mano para crear aplicaciones de diseño limpio.

Buena suerte


Las interfaces no solo son compatibles con el polimorfismo, son esenciales para ello. Parte de la idea que parece faltar es que si uno tiene una interfaz como IPaintable, la expectativa es que cada objeto que lo implementa proporcionará algún método predeterminado para ser pintado, normalmente encapsulando otros métodos que configuren el objeto de alguna manera útil. .

Por ejemplo, una interfaz IPaintable podría definir un método de pintura:

void Paint(ICanvas canvas);

Tenga en cuenta que el método de pintura no dice nada sobre lo que se debe pintar, ni de qué color ni de ninguna otra cosa. Varios objetos para pintar expondrían propiedades para controlar tales cosas. Un método Polygon, por ejemplo, podría disponer de las propiedades OutlineColor y FillColor, junto con un método SetVertices (). Una rutina que desee pintar una gran cantidad de objetos podría aceptar un IEnumerable (de IPaintable) y simplemente llamar a Paint en todos ellos, sin tener que saber nada sobre cómo se pintarán. El hecho de que se pinte un objeto llamando a Paint sin otros parámetros que el lienzo sobre el que se debe pintar de ninguna manera impide que el método Paint realice todo tipo de rellenos de gradientes de fantasía, mapas de textura, trazado de rayos u otros efectos gráficos. El código que está al mando de la pintura no sabría nada de tales cosas, pero los propios objetos que se pueden mantener por IP podrían contener toda la información que necesitaban y, por lo tanto, no necesitarían el código de llamada para proporcionarlos.