与面向对象设计相关的组合是什么?

我听到(并在这个网站上阅读)很多关于“偏爱组合胜过继承”。

但什么是合成?我从人: 哺乳动物: 动物的角度来理解遗传,但是我实在看不到“组成”的定义。.有人能告诉我吗?

43470 次浏览

Composition is simply the parts that make up the whole. A car has wheels, an engine, and seats. Inheritance is a "is a " relationship. Composition is a "has a" relationship.

An example of Composition is where you have an instance of a class within another class, instead of inheriting from it

This page has a good article explaining why people say "favour composition over inheritance" with some examples of why.

Composition refers to combining simple types to make more complex ones. In your example, composition could be:

Animal:
Skin animalSkin
Organs animalOrgans




Mammal::Animal:
Hair/fur mammalFur
warm-blooded-based_cirulation_system heartAndStuff


Person::Mammal:
string firstName
string lastName

If you wanted to go totally composition (and get rid of all inheritance) it would look like this:

Animal:
Skin animalSkin
Organs animalOrgans


Mammal:
private Animal _animalRef
Hair/fur mammalFur
warm-blooded-based_cirulation_system heartAndStuff


Person:
private Mammal _mammalRef
string firstName
string lastName

The advantage to this approach is that the types Mammal and Person do not have to conform to the interface of their previous parent. This could be a good thing because sometimes a change to the superclass can have serious effects on the subclasses. They still can have access to the properties and behaviours of these classes through their private instances of these classes, and if they want to expose these former-superclass behaviours, they can simply wrap them in a public method.

I found a good link with good examples here: http://www.artima.com/designtechniques/compoinh.html

There are three ways to give behavior to a class. You can write that behavior into the class; you can inherit from a class that has the desired behavior; or you can incorporate a class with the desired behavior into your class as a field, or member variable. The last two represent forms of code reuse, and the final one - composition - is generally preferred. It doesn't actually give your class the desired behavior - you still need to call the method on the field - but it puts fewer constraints on your class design and results in easier to test and easier to debug code. Inheritance has its place, but composition should be preferred.

class Engine
{


}


class Automobile
{


}




class Car extends Automobile // car "is a" automobile //inheritance here
{
Engine engine; // car "has a" engine //composition here


}

Composition - Functionality of an object is made up of an aggregate of different classes. In practice, this means holding a pointer to another class to which work is deferred.

Inheritance - Functionality of an object is made up of it's own functionality plus functionality from its parent classes.

As to why composition is preferred over inheritance, take a look at the Circle-ellipse problem.

composition

simply mean using instance variables that are references to other objects.


For an illustration of how inheritance compares to composition in the code reuse department, consider this very simple example:


1- Code via inheritance

    class Fruit {


// Return int number of pieces of peel that
// resulted from the peeling activity.
public int peel() {


System.out.println("Peeling is appealing.");
return 1;
}
}


class Apple extends Fruit {
}


class Example1 {


public static void main(String[] args) {


Apple apple = new Apple();
int pieces = apple.peel();
}
}

When you run the Example1 application, it will print out "Peeling is appealing.", because Apple inherits (reuses) Fruit's implementation of peel(). If at some point in the future, however, you wish to change the return value of peel() to type Peel, you will break the code for Example1. Your change to Fruit breaks Example1's code even though Example1 uses Apple directly and never explicitly mentions Fruit. for more info ref Here's what that would look like:

class Peel {


private int peelCount;


public Peel(int peelCount) {
this.peelCount = peelCount;
}


public int getPeelCount() {


return peelCount;
}
//...
}


class Fruit {


// Return a Peel object that
// results from the peeling activity.
public Peel peel() {


System.out.println("Peeling is appealing.");
return new Peel(1);
}
}


// Apple still compiles and works fine
class Apple extends Fruit {
}


// This old implementation of Example1
// is broken and won't compile.
class Example1 {


public static void main(String[] args) {


Apple apple = new Apple();
int pieces = apple.peel();
}
}

2- Code via composition Composition provides an alternative way for Apple to reuse Fruit's implementation of peel(). Instead of extending Fruit, Apple can hold a reference to a Fruit instance and define its own peel() method that simply invokes peel() on the Fruit. Here's the code:

class Fruit {


// Return int number of pieces of peel that
// resulted from the peeling activity.
public int peel() {


System.out.println("Peeling is appealing.");
return 1;
}
}


class Apple {


private Fruit fruit = new Fruit();


public int peel() {
return fruit.peel();
}
}


class Example2 {


public static void main(String[] args) {


Apple apple = new Apple();
int pieces = apple.peel();
}
}

for more information ref