How do inheritance and composition differ?

I’m wondering about the differences between inheritance and composition examined with concrete code relevant arguments.

In particular my example was:

Inheritance:

class Do:
    def do(self):
        self.doA()
        self.doB()

    def doA(self):
        pass

    def doB(self):
        pass

class MyDo(Do):
    def doA(self):
        print("A")

    def doB(self):
        print("B")

x=MyDo()

vs Composition:

class Do:
    def __init__(self, a, b):
        self.a=a
        self.b=b

    def do(self):
        self.a.do()
        self.b.do()

x=Do(DoA(), DoB())

(Note for composition I’m missing code so it’s not actually shorter)

Can you name particular advantages of one or the other?

I’m think of:

  • composition is useful if you plan to reuse DoA() in another context
  • inheritance seems easier; no additional references/variables/initialization
  • method doA can access internal variable (be it a good or bad thing 🙂 )
  • inheritance groups logic A and B together; even though you could equally introduce a grouped delegate object
  • inheritance provides a preset class for the users; with composition you’d have to encapsule the initialization in a factory so that the user does have to assemble the logic and the skeleton

Basically I’d like to examine the implications of inheritance vs composition. I heard often composition is preferred, but I’d like to understand that by example.

Of course I can always start with one and refactor later to the other.

1

Conceptually speaking, composition models “consists of” relationships, whereas inheritance models “is a”.

Using the car analogy, “a car has wheels” is a textbook example for composition, and it makes sense to have a class Wheel, and a class Car with a property wheels of type Wheel[].

In theory, an example of inheritance would be “a truck is a vehicle”: properties common to all vehicles can be implemented in class Vehicle, while those specific to trucks can be implemented in class Truck.

The truck example, however, also illustrates the problem of the inheritance approach: what if you have to make your vehicle class polymorphic not only for the vehicles purpose (passengers vs. freight), but also for fuel type? You’d have to create four classes to cover passenger cars and freight vehicles, as well as diesel vs. gasoline powered. Add another orthogonal property, and the number of classes doubles again. Worse yet, you have to decide which of these orthogonal properties comes first in the class hierarchy: is it Vehicle -> DieselVehicle -> DieselFreightVehicle -> Truck, or is it Vehicle -> FreightVehicle -> DieselFreightVehicle -> Truck? Either way, you have to duplicate some functionality, either the freight-specific things, or the diesel-specific things. The solution is to use composition anyway: A vehicle has an engine (which can be diesel- or gasonline-powered), and a cargo type (which can be passengers or freight); you don’t need a truck class anymore, because your vehicle class can already model all sorts of vehicles by combining suitable engines and cargo types. Note that the components are still polymorphic, but the container object is not. The trick is to keep polymorphism one-dimensional, that is, each polymorphic hierarchy models one of many orthogonal properties, such as engine type, freight type, etc.

This is why people say “favor composition over inheritance”; of course you are still inheriting, but you have separated your inheritance into independent strains.

It’s depends on the architecture and what you need to resolve.

In your example a client of your code if want to change the implementation of doA, and doB with the inheritance example would need to write a class that extends from MyDo but with composition, just initialize with a class which have the same interface.

Now you need to thing what are the code of.

Suppose the class D before call doA or doB call another methods to perform validation or configurations and then execute doA, the inheritance approach is good.(in this case the client never call doA if not another method that do things and then call doA)

Simple example: Class Component. Class window extends Component. The class component have methods that would be used in class Window, and suppose that you what to add a button of close always, then imagine that you need overwrite the method addChildrens() to add that button. But you never call addChildern() it is doing by the initialize method of Component Class, that have already a life cycle implemented. (Be aware this could be done with different approach)

For composite situation.
MyDo use directly the doA or doB as services, so expect some interface, but need to be flexible, suppose doA and doB read data form some source. Then you can have different implementations of Do whit the different sources.

Simple example: MyDo is a log tool class and doA, doB method log the information. You can have different implementation do Do that log in diferents sources.

I’m be leave that are more examples, but in general it depends of what you need to do with your classes after.

When you use inheritance, a subclass depends on implementation details of its superclass. If the superclass implementation details change, the subclass could break even though its code doesn’t change. When you use composition you’re not dependent on the implementation of a class, only its interface.

If the classes Do and MyDo are in the same package and under the control of the same programmers, it’s generally safe to use inheritance. If you’re aware of the dependencies, you can test the classes together when the superclass implementation changes. If you’re extending a class that’s not under your control (like a class from a standard library) you want to use composition so that a change in implementation details of the library class won’t break your client code.

An important thing to mention is that inheritance should not be for the sole purpose of code re-use, use delegation/composition for this.

Composition would be when we have a class say BroadbandConnection with a method called connection(). Then your manager says we want to add encryption, so you create a class BroadbandConnectionWithEncryption. Your natural instinct may be to use inheritance and then make the new class BroadbandConnectionWithEncryption derive from BroadbandConnection.

Drawback’s to this is that the creator of the initial class had not designed it for inheritance so you would need to change its definition to make the method connection() virtual so you can override its behavior in the derived class. This is not always ideal. A better idea is to use delegation here for the purpose of code reuse.

class BroadBandConnection
{
   public:
   void Connection (string password)
   {
      //connection code.
   }
};

class BroadBandConnectionWithEndcryption
{
   public:
   void Connection (string password)
   {
       mbroadbandconnection.Connection(password);
       //now do some stuff to zero the memory or
       //do some encryption stuff
   }

   private:
   BroadBandConnection mbroadbandconnection;
};

Inheritance: Clients deal with instances of MyDo (or other subclasses). They choose the behavior they want by selecting a given subclass and using it. Best choice when you want to deliver a predetermined and immutable set of behaviors to the client.

Composition: Clients deal directly with instances of Do. They can choose he behavior they want by configuring the object, or by using an appropriate factory method. They may even change an object’s behavior by reconfiguring it on the fly. Best choice when you want to give the client freedom to customize an object.

Imagine that you’re an automobile manufacturer. You’ve got three models: Scoot, Zip, and Fly. All three are based on a common chassis and drive train (which you call Base internally) but have different body styles, interiors, etc. You don’t sell Base as a product; it’s just the foundation for the models that you do sell and not even manufactured as a separate assembly, it’s just the common set of characteristics that the three models share. Scoot, Zip, and Fly are complete packages — they’re like subclasses of Base. All three models are available with various dealer installable options: sunroof, stereo, rocket boosters, etc.

When deciding between inheritance and composition, consider what you want to provide to users. Do you want a given feature to be baked into the product like the wheel base, or do you want it to be a dealer installable option, like a navigation system? Sometimes the choice is obvious; other times it’s a matter of design choices.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật