Sự khác biệt giữa Kế thừa và Thành phần


208

Thành phần và kế thừa có giống nhau không? Nếu tôi muốn triển khai mẫu thành phần, làm thế nào tôi có thể làm điều đó trong Java?


2
Câu hỏi liên quan khác: Có bất cứ điều gì thành phần không thể thực hiện mà thừa kế có thể? stackoverflow.com/questions/2238642/
trộm


1
Bài viết này là hữu ích cho tôi và vì vậy giúp: thoughtworks.com/insights/blog/...
QMaster

Câu trả lời:


321

Họ hoàn toàn khác nhau. Kế thừa là một mối quan hệ "là-một" . Thành phần là "có-a" .

Bạn thực hiện sáng tác bằng cách có một thể hiện của một lớp khác Cnhư một trường của lớp của bạn, thay vì mở rộng C. Một ví dụ điển hình trong đó sáng tác sẽ tốt hơn nhiều so với kế thừa java.util.Stack, hiện đang mở rộng java.util.Vector. Điều này hiện được coi là một sai lầm. Một vectơ "KHÔNG-KHÔNG-a" ; bạn không được phép chèn và loại bỏ các yếu tố tùy ý. Nó nên là thành phần thay thế.

Thật không may, đã quá muộn để khắc phục lỗi thiết kế này, vì việc thay đổi hệ thống phân cấp thừa kế bây giờ sẽ phá vỡ tính tương thích với mã hiện có. Đã Stacksử dụng thành phần thay vì kế thừa, nó luôn có thể được sửa đổi để sử dụng cấu trúc dữ liệu khác mà không vi phạm API .

Tôi đánh giá cao cuốn sách Josh Bloch của Java phiên bản 2 hiệu quả

  • Mục 16: Thành phần ủng hộ thừa kế
  • Mục 17: Thiết kế và tài liệu để thừa kế hoặc nếu không thì cấm

Thiết kế hướng đối tượng tốt không phải là tự do mở rộng các lớp hiện có. Bản năng đầu tiên của bạn nên sáng tác thay thế.


Xem thêm:


4
Hấp dẫn. Tại sao không chỉ tạo một lớp java.util.Stack2 mới sử dụng thành phần?
qed

5
Tôi đánh giá cao câu trả lời này; tuy nhiên, tôi cảm thấy như thể câu trả lời bị lạc hướng và đi sâu vào những lo ngại xung quanh việc thiết kế ngôn ngữ (và một gói cụ thể) hơn là nó trả lời câu hỏi được hỏi về thành phần so với kế thừa. Tôi là một fan hâm mộ lớn của việc trả lời câu hỏi về SO, trích dẫn tài nguyên - không liên kết với các tài nguyên bên ngoài mà không cung cấp một bản tóm tắt sâu hơn so với tổng kết một dòng.
Thomas

5
Ví dụ xấu, tôi đã phải tìm kiếm thêm để hiểu Vector và Stack là gì.
Sam Ramezanli

Tốt nhưng ví dụ của bạn về java chồng không phải là một ứng cử viên tốt vì thừa kế này là một mẫu của quyết định xấu về việc chọn thừa kế trên thành phần như đã nói trong bài viết này: thoughtworks.com/insights/blog/...
QMaster

212

Thành phần có nghĩa là HAS A
Kế thừaIS A

Example: Xe Động cơ và Xe Ô tô.

Trong lập trình, điều này được thể hiện như sau:

class Engine {} // The Engine class.

class Automobile {} // Automobile class which is parent to Car class.

class Car extends Automobile { // Car is an Automobile, so Car class extends Automobile class.
  private Engine engine; // Car has an Engine so, Car class has an instance of Engine class as its member.
}

7
Tôi muốn đổi "ô tô" thành "xe chạy bằng điện" như trong nhiều cách hiểu ô tô và ô tô là tương đương.
nanofarad

5
@hexafraction Tôi đồng ý rằng Xe có thể là một lựa chọn tốt hơn, nhưng đồng thời -codaddict- đã minh họa điểm tốt cho những gì đã được hỏi.
nckbrz

5
"một động cơ":-/
Omar Tariq

độc đáo phơi bày. +1. đọc thêm javarevisited.blogspot.in/2015/06/ từ
roottraveller

@AndreyAkhmetov Ô tô có thể có typelĩnh vực LoạiEnum
Ojonugwa Jude Ochalifu

42

Làm thế nào thừa kế có thể nguy hiểm?

Hãy lấy một ví dụ

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

1) Như rõ ràng trong đoạn mã trên, Class Y có khả năng khớp nối rất mạnh với lớp X. Nếu có bất kỳ thay đổi nào trong siêu lớp X, Y có thể bị hỏng đáng kể. Giả sử Trong lớp X trong tương lai thực hiện một phương thức hoạt động với chữ ký dưới đây

public int work(){
}

Thay đổi được thực hiện trong lớp X nhưng nó sẽ làm cho lớp Y không thể hoàn thành. Vì loại phụ thuộc này có thể lên đến bất kỳ cấp độ nào và nó có thể rất nguy hiểm. Mỗi khi siêu lớp có thể không có khả năng hiển thị đầy đủ để mã bên trong tất cả các lớp con và lớp con của nó có thể luôn chú ý đến những gì đang xảy ra trong siêu lớp mọi lúc. Vì vậy, chúng ta cần tránh khớp nối mạnh mẽ và không cần thiết này.

Làm thế nào để thành phần giải quyết vấn đề này?

Hãy xem bằng cách sửa đổi ví dụ tương tự

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

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

Ở đây chúng ta đang tạo tham chiếu của lớp X trong lớp Y và gọi phương thức của lớp X bằng cách tạo một thể hiện của lớp X. Bây giờ tất cả các khớp nối mạnh mẽ đã biến mất. Hiện tại, siêu lớp và lớp con rất độc lập với nhau. Các lớp có thể tự do thực hiện các thay đổi gây nguy hiểm trong tình huống thừa kế.

2) Ưu điểm thứ hai rất tốt của bố cục ở chỗ Nó cung cấp tính linh hoạt khi gọi phương thức, ví dụ:

class X implements R
{}
class Y implements R
{}

public class Test{    
    R r;    
}

Trong lớp Test sử dụng tham chiếu r tôi có thể gọi các phương thức của lớp X cũng như lớp Y. Sự linh hoạt này không bao giờ có trong thừa kế

3) Một lợi thế lớn khác: Kiểm tra đơn vị

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

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

Trong ví dụ trên, nếu không biết trạng thái của x, nó có thể dễ dàng bị giả lập bằng cách sử dụng một số dữ liệu thử nghiệm và tất cả các phương pháp có thể được kiểm tra dễ dàng. Điều này hoàn toàn không thể xảy ra khi thừa kế vì bạn phụ thuộc rất nhiều vào siêu lớp để có được trạng thái và thực hiện bất kỳ phương thức nào.

4) Một lý do chính đáng khác tại sao chúng ta nên tránh kế thừa là Java không hỗ trợ nhiều kế thừa.

Hãy lấy một ví dụ để hiểu điều này:

Public class Transaction {
    Banking b;
    public static void main(String a[])    
    {    
        b = new Deposit();    
        if(b.deposit()){    
            b = new Credit();
            c.credit();    
        }
    }
}

Điều tốt để biết:

  1. thành phần dễ dàng đạt được trong thời gian chạy trong khi kế thừa cung cấp các tính năng của nó tại thời gian biên dịch

  2. thành phần còn được gọi là quan hệ và thừa kế HAS-A còn được gọi là quan hệ IS-A

Vì vậy, hãy tạo thói quen luôn thích sáng tác hơn thừa kế vì nhiều lý do trên.


3
đồng ý nhưng đưa ra giải pháp của bạn bằng cách sử dụng thành phần .... chúng tôi vẫn cần làm một người giữ trẻ, ví dụ như bây giờ siêu lớp X thay đổi tên phương thức từ làm sang làm .... thì lớp con Y cũng sẽ cần được duy trì (cần phải thay đổi cũng như) đây vẫn là khớp nối chặt chẽ? Và làm thế nào để chúng ta thoát khỏi nó?
kẹt vào

19

Câu trả lời được đưa ra bởi @Michael Coleues là không chính xác (tôi xin lỗi; tôi không thể nhận xét trực tiếp) và có thể dẫn đến một số nhầm lẫn.

Triển khai giao diện là một hình thức thừa kế ... khi bạn triển khai một giao diện, bạn không chỉ kế thừa tất cả các hằng số, bạn đang cam kết đối tượng của bạn thuộc loại được chỉ định bởi giao diện; nó vẫn là một mối quan hệ " là-một ". Nếu một chiếc xe thực hiện Fillable , chiếc xe " is-a " Fillable và có thể được sử dụng trong mã của bạn bất cứ nơi nào bạn sẽ sử dụng Fillable .

Thành phần về cơ bản là khác với thừa kế. Khi bạn sử dụng bố cục, bạn (như các câu trả lời khác lưu ý) tạo mối quan hệ " có-có " giữa hai đối tượng, trái ngược với mối quan hệ " is-a " mà bạn thực hiện khi bạn sử dụng tính kế thừa .

Vì vậy, từ các ví dụ về xe hơi trong các câu hỏi khác, nếu tôi muốn nói rằng một chiếc xe " bình xăng", tôi sẽ sử dụng bố cục, như sau:

public class Car {

private GasTank myCarsGasTank;

}

Hy vọng rằng sẽ xóa mọi hiểu lầm.


17

Kế thừa mang lại mối quan hệ IS-A . Thành phần mang lại mối quan hệ HAS-A . Mẫu chiến lược giải thích rằng Thành phần nên được sử dụng trong trường hợp có các họ thuật toán xác định một hành vi cụ thể.
Ví dụ cổ điển là lớp vịt thực hiện hành vi bay.

public interface Flyable{
 public void fly();
}

public class Duck {
 Flyable fly;

 public Duck(){
  fly = new BackwardFlying();
 }
}

Vì vậy, chúng ta có thể có nhiều lớp thực hiện bay, ví dụ:

public class BackwardFlying implements Flyable{
  public void fly(){
    Systemout.println("Flies backward ");
  }
}
public class FastFlying implements Flyable{
  public void fly(){
    Systemout.println("Flies 100 miles/sec");
  }
}

Nếu được thừa kế, chúng ta sẽ có hai lớp chim khác nhau thực hiện chức năng bay đi bay lại. Vì vậy, kế thừa và thành phần là hoàn toàn khác nhau.


7

Bố cục giống như âm thanh - bạn tạo một đối tượng bằng cách cắm vào các phần.

EDIT phần còn lại của câu trả lời này là sai dựa trên tiền đề sau.
Điều này được thực hiện với Giao diện.
Ví dụ: sử dụng Carví dụ trên,

Car implements iDrivable, iUsesFuel, iProtectsOccupants
Motorbike implements iDrivable, iUsesFuel, iShortcutThroughTraffic
House implements iProtectsOccupants
Generator implements iUsesFuel

Vì vậy, với một vài thành phần lý thuyết tiêu chuẩn, bạn có thể xây dựng đối tượng của mình. Sau đó, công việc của bạn là điền vào cách thức Housebảo vệ người cư ngụ và cách Carbảo vệ người cư ngụ.

Kế thừa giống như cách khác. Bạn bắt đầu với một đối tượng hoàn chỉnh (hoặc bán hoàn chỉnh) và bạn thay thế hoặc Ghi đè các bit khác nhau mà bạn muốn thay đổi.

Ví dụ, MotorVehiclecó thể đi kèm với một Fuelablephương pháp và Drivephương pháp. Bạn có thể rời khỏi phương pháp Nhiên liệu vì nó giống nhau khi đổ đầy xe máy và ô tô, nhưng bạn có thể ghi đè Drivephương thức này vì Xe máy lái rất khác so với a Car.

Với tính kế thừa, một số lớp đã được triển khai hoàn toàn và các lớp khác có các phương thức mà bạn buộc phải ghi đè. Với Thành phần không có gì được trao cho bạn. (nhưng bạn có thể Thực hiện các giao diện bằng cách gọi các phương thức trong các lớp khác nếu bạn tình cờ có thứ gì đó nằm xung quanh).

Thành phần được xem là linh hoạt hơn, bởi vì nếu bạn có một phương thức như iUsesFuel, bạn có thể có một phương thức ở một nơi khác (một lớp khác, một dự án khác) mà chỉ lo lắng về việc xử lý các vật thể có thể được cung cấp nhiên liệu, bất kể đó là xe hơi, thuyền, bếp, thịt nướng, v.v. Các giao diện bắt buộc các lớp nói rằng chúng thực hiện giao diện đó thực sự có các phương thức mà giao diện đó là tất cả. Ví dụ,

iFuelable Interface:
   void AddSomeFuel()
   void UseSomeFuel()
   int  percentageFull()

sau đó bạn có thể có một phương pháp ở nơi khác

private void FillHerUp(iFuelable : objectToFill) {

   Do while (objectToFill.percentageFull() <= 100)  {

        objectToFill.AddSomeFuel();
   }

Ví dụ kỳ lạ, nhưng nó cho thấy phương thức này không quan tâm đến những gì nó lấp đầy, bởi vì đối tượng thực hiện iUsesFuel, nó có thể được lấp đầy. Kết thúc câu chuyện.

Nếu bạn đã sử dụng Kế thừa thay thế, bạn sẽ cần các FillHerUpphương thức khác nhau để xử lý MotorVehiclesBarbecues, trừ khi bạn có một số đối tượng cơ bản "ObjectThatUsesFuel" khá kỳ lạ để kế thừa.


Các quy ước Java nói rằng các tên lớp và giao diện được viết ThisCase, không phải trong camelCase. Do đó, tốt nhất là đặt tên cho các giao diện của bạn IDrivable, v.v. Bạn có thể không cần "Tôi" nếu bạn tập hợp lại tất cả các giao diện của mình thành một gói chính xác.
ThePyroEagle

6

Thành phần và kế thừa có giống nhau không?

Chúng không giống nhau.

Thành phần : Nó cho phép một nhóm các đối tượng phải được xử lý theo cùng một cách như một thể hiện của một đối tượng. Mục đích của hỗn hợp là "kết hợp" các đối tượng thành các cấu trúc cây để thể hiện hệ thống phân cấp toàn bộ

Kế thừa : Một lớp kế thừa các trường và phương thức từ tất cả các siêu lớp của nó, cho dù trực tiếp hay gián tiếp. Một lớp con có thể ghi đè các phương thức mà nó kế thừa hoặc nó có thể ẩn các trường hoặc các phương thức mà nó kế thừa.

Nếu tôi muốn triển khai mẫu thành phần, làm thế nào tôi có thể làm điều đó trong Java?

Bài viết Wikipedia là đủ tốt để thực hiện mô hình tổng hợp trong java.

nhập mô tả hình ảnh ở đây

Những người tham gia chính:

Thành phần :

  1. Là sự trừu tượng cho tất cả các thành phần, bao gồm cả các thành phần tổng hợp
  2. Khai báo giao diện cho các đối tượng trong thành phần

:

  1. Đại diện cho các đối tượng lá trong thành phần
  2. Thực hiện tất cả các phương thức Thành phần

Hợp chất :

  1. Đại diện cho một thành phần hỗn hợp (thành phần có con)
  2. Thực hiện các phương pháp để thao túng trẻ em
  3. Thực hiện tất cả các phương thức Thành phần, thường bằng cách ủy thác chúng cho con của nó

Ví dụ mã để hiểu mẫu tổng hợp :

import java.util.List;
import java.util.ArrayList;

interface Part{
    public double getPrice();
    public String getName();
}
class Engine implements Part{
    String name;
    double price;
    public Engine(String name,double price){
        this.name = name;
        this.price = price;
    }
    public double getPrice(){
        return price;
    }
    public String getName(){
        return name;
    }
}
class Trunk implements Part{
    String name;
    double price;
    public Trunk(String name,double price){
        this.name = name;
        this.price = price;
    }
    public double getPrice(){
        return price;
    }
    public String getName(){
        return name;
    }
}
class Body implements Part{
    String name;
    double price;
    public Body(String name,double price){
        this.name = name;
        this.price = price;
    }
    public double getPrice(){
        return price;
    }
    public String getName(){
        return name;
    }
}
class Car implements Part{
    List<Part> parts;
    String name;

    public Car(String name){
        this.name = name;
        parts = new ArrayList<Part>();
    }
    public void addPart(Part part){
        parts.add(part);
    }
    public String getName(){
        return name;
    }
    public String getPartNames(){
        StringBuilder sb = new StringBuilder();
        for ( Part part: parts){
            sb.append(part.getName()).append(" ");
        }
        return sb.toString();
    }
    public double getPrice(){
        double price = 0;
        for ( Part part: parts){
            price += part.getPrice();
        }
        return price;
    }   
}

public class CompositeDemo{
    public static void main(String args[]){
        Part engine = new Engine("DiselEngine",15000);
        Part trunk = new Trunk("Trunk",10000);
        Part body = new Body("Body",12000);

        Car car = new Car("Innova");
        car.addPart(engine);
        car.addPart(trunk);
        car.addPart(body);

        double price = car.getPrice();

        System.out.println("Car name:"+car.getName());
        System.out.println("Car parts:"+car.getPartNames());
        System.out.println("Car price:"+car.getPrice());
    }

}

đầu ra:

Car name:Innova
Car parts:DiselEngine Trunk Body
Car price:37000.0

Giải trình:

  1. Một phần là một chiếc lá
  2. Xe chứa nhiều bộ phận
  3. Các bộ phận khác nhau của xe đã được thêm vào Xe
  4. Giá xe = tổng của (Giá của mỗi phần )

Tham khảo câu hỏi dưới đây để biết ưu và nhược điểm của thành phần và kế thừa.

Thích thành phần hơn thừa kế?


Liệu nó có ý nghĩa để thực hiện các bộ phận cho lớp xe là tốt. Sẽ không tốt nếu bạn sử dụng nó làm sáng tác
bhalkian 20/03/18

4

như một ví dụ khác, hãy xem xét một lớp xe hơi, đây sẽ là một cách sử dụng tốt về bố cục, một chiếc xe sẽ "có" một động cơ, hộp số, lốp xe, ghế ngồi, v.v. Nó sẽ không mở rộng bất kỳ lớp nào trong số đó.


4

Thành phần là nơi một cái gì đó được tạo thành từ các phần riêng biệt và nó có mối quan hệ chặt chẽ với các phần đó. Nếu phần chính chết đi, những người khác cũng không thể có một cuộc sống của riêng họ. Một ví dụ thô là cơ thể con người. Lấy ra trái tim và tất cả các phần khác chết đi.

Kế thừa là nơi bạn chỉ cần lấy một cái gì đó đã tồn tại và sử dụng nó. Không có mối quan hệ mạnh mẽ. Một người có thể thừa kế gia sản của cha mình nhưng anh ta có thể làm mà không cần nó.

Tôi không biết Java vì vậy tôi không thể cung cấp một ví dụ nhưng tôi có thể cung cấp giải thích về các khái niệm.


3

Kế thừa giữa hai lớp, trong đó một lớp mở rộng một lớp khác thiết lập mối quan hệ " IS A ".

Thành phần ở đầu bên kia chứa một thể hiện của một lớp khác trong lớp của bạn thiết lập mối quan hệ " Có A ". Thành phần trong java là hữu ích vì về mặt kỹ thuật tạo điều kiện cho nhiều kế thừa.


3

Trong tập hợp từ đơn giản có nghĩa là có một mối quan hệ ..

Thành phần là một trường hợp đặc biệt của tập hợp . Theo một cách cụ thể hơn, một tập hợp hạn chế được gọi là thành phần. Khi một đối tượng chứa đối tượng khác, nếu đối tượng được chứa không thể tồn tại mà không có sự tồn tại của đối tượng container, thì nó được gọi là thành phần. Ví dụ: Một lớp chứa sinh viên. Một học sinh không thể tồn tại mà không có một lớp học. Có thành phần tồn tại giữa lớp và sinh viên.

Tại sao sử dụng Uẩn

Mã tái sử dụng

Khi sử dụng tổng hợp

Tái sử dụng mã cũng đạt được tốt nhất bằng cách tổng hợp khi không có tàu quan hệ

Di sản

Thừa kế là một mối quan hệ cha mẹ Con cái Kế thừa là một mối quan hệ

Kế thừa trong java là một cơ chế trong đó một đối tượng có được tất cả các thuộc tính và hành vi của đối tượng cha.

Sử dụng tính kế thừa trong khả năng sử dụng lại mã Java 1. 2 Thêm tính năng bổ sung trong lớp con cũng như ghi đè phương thức (để có thể đạt được tính đa hình thời gian chạy).


1

Mặc dù cả Kế thừa và Thành phần đều cung cấp khả năng sử dụng lại mã, nhưng điểm khác biệt chính giữa Thành phần và Kế thừa trong Java là Thành phần cho phép sử dụng lại mã mà không cần mở rộng mã nhưng đối với Kế thừa, bạn phải mở rộng lớp cho bất kỳ việc sử dụng lại mã hoặc chức năng nào. Một điểm khác biệt xuất phát từ thực tế này là bằng cách sử dụng Thành phần, bạn có thể sử dụng lại mã cho lớp cuối cùng không thể mở rộng nhưng Kế thừa không thể sử dụng lại mã trong các trường hợp như vậy. Ngoài ra, bằng cách sử dụng Thành phần, bạn có thể sử dụng lại mã từ nhiều lớp vì chúng được khai báo là biến thành viên, nhưng với Kế thừa, bạn có thể sử dụng lại mẫu mã chỉ một lớp vì trong Java bạn chỉ có thể mở rộng một lớp, vì nhiều Kế thừa không được hỗ trợ trong Java . Bạn có thể làm điều này trong C ++ vì có một lớp có thể mở rộng nhiều hơn một lớp. BTW, bạn nên luôn luônthích Sáng tác hơn Kế thừa trong Java , không chỉ tôi mà ngay cả Joshua Bloch cũng đã gợi ý trong cuốn sách của mình


1
Tại sao tôi nên "thành phần quan trọng hơn kế thừa "? Chúng là các khái niệm khác nhau và được sử dụng cho các mục đích khác nhau. Thành thật mà nói, tôi không thấy làm thế nào bạn thậm chí có thể đi từ người này sang người khác.
Kröw

1

Tôi nghĩ ví dụ này giải thích rõ ràng sự khác biệt giữa thừa kếthành phần .

Trong exmple này, vấn đề được giải quyết bằng cách sử dụng kế thừa và thành phần. Tác giả chú ý đến thực tế rằng; trong kế thừa , một thay đổi trong siêu lớp có thể gây ra vấn đề trong lớp dẫn xuất, kế thừa nó.

Ở đó bạn cũng có thể thấy sự khác biệt về đại diện khi bạn sử dụng UML cho kế thừa hoặc thành phần.

http://www.javaworld.com/article/2076814/core-java/inherribution-versus-compocation--which-one-should-you-choose-.html


1
Liên kết chỉ trả lời được khuyến khích bởi vì họ đi cũ. Vui lòng bao gồm ít nhất các thông tin liên quan quan trọng nhất từ ​​liên kết trong câu trả lời của bạn.
Scott Solmer

1

Kế thừa Vs Thành phần.

Kế thừa và thành phần cả hai được sử dụng để tái sử dụng và mở rộng hành vi của lớp.

Kế thừa chủ yếu sử dụng trong mô hình lập trình thuật toán gia đình như kiểu quan hệ IS-A có nghĩa là loại đối tượng tương tự. Thí dụ.

  1. Duster là một chiếc xe hơi
  2. Safari là một chiếc xe hơi

Những thứ này thuộc về gia đình Car.

Thành phần đại diện cho mối quan hệ HAS-A Type. Nó cho thấy khả năng của một đối tượng như Duster có Five Gears, Safari có bốn Gears, vv Bất cứ khi nào chúng ta cần mở rộng khả năng của một lớp hiện có thì hãy sử dụng thành phần. Ví dụ chúng ta cần thêm một thiết bị nữa trong đối tượng Duster sau đó chúng ta phải tạo thêm một đối tượng bánh răng và kết hợp nó với đối tượng khăn lau.

Chúng ta không nên thực hiện các thay đổi trong lớp cơ sở cho đến khi / trừ khi tất cả các lớp dẫn xuất cần các chức năng đó. Đối với kịch bản này, chúng ta nên sử dụng Thành phần.

lớp A Xuất phát từ lớp B

Lớp A Xuất phát từ lớp C

Lớp A Xuất phát từ lớp D.

Khi chúng ta thêm bất kỳ chức năng nào trong lớp A thì nó có sẵn cho tất cả các lớp con ngay cả khi Lớp C và D không yêu cầu các chức năng đó. Đối với kịch bản này, chúng ta cần tạo một lớp riêng cho các chức năng đó và kết hợp nó với lớp được yêu cầu ( đây là lớp B).

Dưới đây là ví dụ:

          // This is a base class
                 public abstract class Car
                    {
                       //Define prototype
                       public abstract void color();
                       public void Gear() {
                           Console.WriteLine("Car has a four Gear");
                       }
                    }


           // Here is the use of inheritence
           // This Desire class have four gears.
          //  But we need to add one more gear that is Neutral gear.

          public class Desire : Car
                   {
                       Neutral obj = null;
                       public Desire()
                       {
     // Here we are incorporating neutral gear(It is the use of composition). 
     // Now this class would have five gear. 

                           obj = new Neutral();
                           obj.NeutralGear();
                       }

                       public override void color()
                       {
                           Console.WriteLine("This is a white color car");
                       }

                   }


             // This Safari class have four gears and it is not required the neutral
             //  gear and hence we don't need to compose here.

                   public class Safari :Car{
                       public Safari()
                       { }

                       public override void color()
                       {
                           Console.WriteLine("This is a red color car");
                       }


                   }

   // This class represents the neutral gear and it would be used as a composition.

   public class Neutral {
                      public void NeutralGear() {
                           Console.WriteLine("This is a Neutral Gear");
                       }
                   }

0

Thành phần có nghĩa là tạo một đối tượng cho một lớp có quan hệ với lớp cụ thể đó. Giả sử Sinh viên có quan hệ với Tài khoản;

Một thừa kế là, đây là lớp trước với tính năng mở rộng. Điều đó có nghĩa là lớp mới này là lớp Cũ với một số tính năng mở rộng. Giả sử sinh viên là sinh viên nhưng tất cả sinh viên là con người. Vì vậy, có một mối quan hệ với sinh viên và con người. Đây là sự kế thừa.


0

Không, cả hai đều khác nhau. Thành phần tuân theo mối quan hệ "HAS-A" và kế thừa theo mối quan hệ "IS-A". Ví dụ tốt nhất cho thành phần là mô hình chiến lược.


2
Chất lượng bình luận duy nhất của nó
Mathews Sunny

Bạn vừa bình luận điều tương tự câu trả lời được chấp nhận đã nói 7 năm trước bạn?
Anjil Dhamala

0

Kế thừa có nghĩa là sử dụng lại chức năng hoàn chỉnh của một lớp, Ở đây, lớp của tôi phải sử dụng tất cả các phương thức của siêu lớp và lớp của tôi sẽ được kết hợp chính xác với siêu lớp và mã sẽ được sao chép trong cả hai lớp trong trường hợp kế thừa.

Nhưng chúng ta có thể khắc phục từ tất cả những vấn đề này khi chúng ta sử dụng bố cục để nói chuyện với một lớp khác. thành phần đang khai báo một thuộc tính của một lớp khác vào lớp của tôi mà chúng ta muốn nói chuyện. và chức năng nào chúng ta muốn từ lớp đó chúng ta có thể nhận được bằng cách sử dụng thuộc tính đó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.