composition vs inheritance


composition hiểu đơn giản là nó có thành phần của các class khác (theo wiki)

còn inheritance thì nó mang tính kế thừa nghĩa là sẽ có tất cả cái gì trong class khác


ví dụ cho dễ hiểu


vấn đề

  public class X{
    public void do(){
    }
  }
  Public Class Y extends X{
    public void work(){
        do();
    }
  }
  

ta tháy class y có kết nói mạnh với class x (inheritance). nếu class x thay đổi có thể sẽ dẫn đến class y hỏng nghiêm trọng

giả sử trong tương lai ta thêm 1 method work vào class x

    public int work(){
  }
  

class x được thay đổi nhưng sẽ dẫn đến class y ko thể thực hiện

vậy trong tương lai sẽ còn có nhiều các thay đổi ở class x mà mình không thể biết nó có dẫn tới thay đổi ở các subclass không


nên để tránh trường hợp trên ta sẽ dùng composition

vẫn ví dụ trên ta sẽ thay đổi nó 1 chút

    public class X{
      public void do(){
      }
  }

  Public Class Y{
      X x = new X();
      public void work(){
          x.do();
      }
  }
  

ta tạo 1 reference của class x trong y class và lấy method trong x class bằng cách tạo 1 instance của class x

vậy giờ class y không còn mối quan hệ ràng buộc với x. class x có thể thay đổi mà không dẫn đến thay đổi của class y


1 vài lý do không nên dùng inheritance (TL;DR)


The fragile base class problem

class có tính inheritance có quan hệ chặt chẽ nên có thể 1 vài thay đổi nhỏ ở base class sẽ dẫn đến child class bị hỏng


The gorilla/banana problem

class inheritance thì không thể chọn được code nào trong base class để dùng. nhưng composition thì có thể

dẫn đến trường hợp mình muốn lấy quả chuối nhưng lại lấy cả con khỉ cầm quả chuối và cả khu rừng