Heim  >  Artikel  >  Java  >  Zusammensetzung vs. Vererbung

Zusammensetzung vs. Vererbung

DDD
DDDOriginal
2024-09-25 11:45:44362Durchsuche

Composición vs Herencia

Einführung

Vererbung und Zusammensetzung sind zwei grundlegende Konzepte in der objektorientierten Programmierung (OOP), aber sie werden unterschiedlich verwendet und haben unterschiedliche Zwecke. Das Ziel dieses Beitrags besteht darin, diese Zwecke zu besprechen und einige Dinge zu besprechen, die bei der Auswahl zu beachten sind.

Konzepte der Vererbung

Wenn wir über die Anwendung des Erbes in unseren Designs nachdenken, müssen wir Folgendes verstehen:

  • Definition: Bei der Vererbung kann eine Klasse (abgeleitete Klasse oder Unterklasse genannt) Eigenschaften und Verhaltensweisen von einer anderen Klasse (Basisklasse oder Superklasse genannt) erben. Die abgeleitete Klasse kann die Funktionalität der Basisklasse erweitern oder ändern.
  • Beziehung: Es handelt sich um eine Beziehung „ist ein“ (is-a). Wenn Sie beispielsweise eine Klasse „Fahrzeug“ und eine andere Klasse „Auto“ haben, ist die Klasse „Auto“ eine Unterklasse von „Fahrzeug“.
  • Vorteile: Fördert die Wiederverwendung von Code und ermöglicht eine einfache Erweiterung der Funktionalität.

Kompositionskonzepte

Andererseits, wenn wir darüber nachdenken, Objekte miteinander zu komponieren:

  • Definition: In der Komposition enthält ein Objekt andere Objekte und delegiert einen Teil seiner Funktionalität an diese. Anstelle von Vererbung nutzt eine Klasse Instanzen anderer Klassen, um ihre Funktionalität zu erreichen.
  • Beziehung: Es handelt sich um eine „hat-ein“-Beziehung (has-a). Wenn Sie beispielsweise eine Klasse „Motor“ und eine Klasse „Auto“ haben, kann die Klasse „Auto“ ein Objekt der Klasse „Motor“ haben.
  • Vorteile: Größere Flexibilität und weniger Kopplung zwischen den Klassen. Änderungen in einer Klasse wirken sich nicht direkt auf die andere aus.

Warum eine Erbschaftskomposition?

Die Frage, ob Komposition besser ist als Vererbung oder umgekehrt, ist ein umstrittenes Thema im Software-Design. Beide Ansätze haben ihre Vor- und Nachteile, und die Wahl hängt vom spezifischen Projektkontext und den Anforderungen ab. Hier präsentiere ich Ihnen ein Beispiel, bei dem die Zusammensetzung der Vererbung vorzuziehen sein kann.

Sehen wir uns ein Beispiel in Java an, das zeigt, wie die Komposition in bestimmten Fällen der Vererbung vorzuziehen sein kann. Angenommen, wir arbeiten an einem Bestellabwicklungssystem in einem Online-Shop.

  • Vererbungsansatz:

Betrachten wir zunächst einen Ansatz, der die Vererbung nutzt, um verschiedene Arten von Produkten darzustellen, die gekauft werden können, z. B. Bücher und Elektronik:

// Clase base para productos
class Producto {
    String nombre;
    double precio;

    Producto(String nombre, double precio) {
        this.nombre = nombre;
        this.precio = precio;
    }

    void procesarPedido() {
        System.out.println("Procesando pedido para " + nombre);
    }
}

// Clase para productos electrónicos que hereda de Producto
class ProductoElectronico extends Producto {
    String modelo;

    ProductoElectronico(String nombre, double precio, String modelo) {
        super(nombre, precio);
        this.modelo = modelo;
    }
}

// Clase para libros que hereda de Producto
class Libro extends Producto {
    String autor;

    Libro(String nombre, double precio, String autor) {
        super(nombre, precio);
        this.autor = autor;
    }
}

Dieser Ansatz funktioniert, aber was ist, wenn Sie neue Produkttypen einführen oder spezifische Funktionen für bestimmte Produkttypen hinzufügen müssen?

  • Konzentrieren Sie sich auf die Komposition:

Anstatt uns ausschließlich auf die Vererbung zu verlassen, könnten wir die Komposition verwenden, um verschiedene Arten von Produkten flexibler zu handhaben:

// Clase para productos
class Producto {
    String nombre;
    double precio;

    Producto(String nombre, double precio) {
        this.nombre = nombre;
        this.precio = precio;
    }

    void procesarPedido() {
        System.out.println("Procesando pedido para " + nombre);
    }
}

// Clase para productos electrónicos que utiliza composición
class ProductoElectronico {
    Producto producto;
    String modelo;

    ProductoElectronico(String nombre, double precio, String modelo) {
        this.producto = new Producto(nombre, precio);
        this.modelo = modelo;
    }

    // Puedes agregar lógica específica para productos electrónicos si es necesario
    void procesarPedidoEspecifico() {
        System.out.println("Procesando pedido específico para " + producto.nombre);
    }
}

// Clase para libros que utiliza composición
class Libro {
    Producto producto;
    String autor;

    Libro(String nombre, double precio, String autor) {
        this.producto = new Producto(nombre, precio);
        this.autor = autor;
    }

    // Puedes agregar lógica específica para libros si es necesario
    void procesarPedidoEspecifico() {
        System.out.println("Procesando pedido específico para " + producto.nombre);
    }
}

Bei diesem Ansatz verfügt jeder Produkttyp über eine Instanz der Produktklasse, wodurch eine gemeinsame Logik für die Auftragsabwicklung ermöglicht wird. Darüber hinaus kann jeder Produkttyp mithilfe von Methoden wie „processSpecificOrder()“ über eine eigene spezifische Logik verfügen. Dieses Design ist flexibler und erleichtert die Einführung neuer Produkttypen oder die Änderung der typspezifischen Logik, ohne die Vererbungshierarchie zu beeinträchtigen.

Wann soll die Erbschaft beantragt werden?

Während die Wahl zwischen Vererbung und Komposition beim Softwaredesign vom Kontext und den spezifischen Anforderungen des Problems abhängt, mit dem Sie sich befassen. Hier sind einige Situationen, in denen Sie die Vererbung als geeignetere Option als die Komposition in Betracht ziehen könnten:

  • Relación "es-un": La herencia es especialmente adecuada cuando hay una relación clara de "es-un" entre las clases. Si una clase B es una versión más específica o especializada de una clase A, entonces la herencia tiene sentido. Por ejemplo, si tienes una clase Vehiculo y una clase Automovil, la relación "es-un" es clara, ya que un automóvil es un tipo de vehículo.
class Vehiculo {
    // ...
}

class Automovil extends Vehiculo {
    // ...
}
  • Reutilización de código: La herencia permite la reutilización de código, ya que la clase derivada hereda los miembros y métodos de la clase base. Esto puede ser beneficioso cuando hay una cantidad significativa de código común entre las clases relacionadas.
class Animal {
    void comer() {
        // Lógica común para comer
    }
}

class Perro extends Animal {
    void ladrar() {
        // Lógica específica para ladrar
    }
}
  • Polimorfismo: La herencia es fundamental para la implementación del polimorfismo, que permite a las clases derivadas proporcionar implementaciones específicas de los métodos heredados de la clase base. Esto es útil en escenarios donde necesitas tratar objetos de clases derivadas de manera uniforme.
class Figura {
    void dibujar() {
        // Lógica común para dibujar una figura
    }
}

class Circulo extends Figura {
    void dibujar() {
        // Lógica específica para dibujar un círculo
    }
}

class Cuadrado extends Figura {
    void dibujar() {
        // Lógica específica para dibujar un cuadrado
    }
}

  • Extensiones de funcionalidad: Si estás extendiendo o especializando funcionalidad existente, la herencia puede ser más natural. Por ejemplo, si estás desarrollando una biblioteca y proporcionas una clase base con una funcionalidad básica, los usuarios de tu biblioteca pueden derivar de esa clase base para extender esa funcionalidad.

Que pasa si hacemos una mala herencia?

Si seguimos evaluando los pros y los contras de la herencia, uno de los problemas que puede surgir de una mala herencia es que violaríamos el Principio de Segregación de Interfaces, que indica que los clientes no deberían verse obligados a depender de interfaces que no utilizan. Si una interfaz se extiende de manera que incluya métodos que no son relevantes para todas las implementaciones, los clientes que utilizan esa interfaz podrían verse forzados a implementar o depender de métodos que no necesitan, lo que puede llevar a un diseño menos limpio y más difícil de mantener.

Conclusión

En resumen, la herencia se centra en la relación "es un" y se utiliza para modelar jerarquías de clases, mientras que la composición se centra en la relación "tiene un" y se utiliza para construir objetos complejos a partir de otros objetos más simples. Ambos enfoques tienen sus casos de uso específicos y se eligen según la estructura y la naturaleza de las relaciones en el diseño del software.

Das obige ist der detaillierte Inhalt vonZusammensetzung vs. Vererbung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:Kapitel 7 AbschlusstestsNächster Artikel:Kapitel 7 Abschlusstests