ความแตกต่างระหว่างมรดกและองค์ประกอบ


208

องค์ประกอบและมรดกมีเหมือนกันหรือไม่? หากฉันต้องการใช้รูปแบบการแต่งเพลงฉันจะทำสิ่งนั้นใน Java ได้อย่างไร


2
คำถามที่เกี่ยวข้องอื่น ๆ : มีองค์ประกอบอะไรที่ไม่สามารถทำให้มรดกสำเร็จได้หรือไม่? stackoverflow.com/questions/2238642/…
ewernli

1
โปรดดูis-a-vs-has-a-a-one-is-better
nawfal

1
บทความนี้มีประโยชน์สำหรับฉันและได้รับความช่วยเหลือดังนี้: thinkworks.com/insights/blog/…
QMaster

คำตอบ:


321

พวกเขาแตกต่างกันอย่างสิ้นเชิง การรับมรดกคือความสัมพันธ์"is-a" องค์ประกอบเป็น"มี-A"

คุณทำองค์ประกอบโดยมีตัวอย่างของการเรียนอื่นเป็นด้านการเรียนของคุณแทนการขยายC Cเป็นตัวอย่างที่ดีที่องค์ประกอบจะได้รับมากดีกว่ามรดกซึ่งปัจจุบันขยายjava.util.Stack java.util.Vectorตอนนี้ถือว่าเป็นความผิดพลาด สแต็ก"is-NOT-a" vector คุณไม่ควรได้รับอนุญาตให้แทรกและลบองค์ประกอบโดยพลการ มันควรจะเป็นองค์ประกอบแทน

น่าเสียดายที่มันสายเกินไปที่จะแก้ไขข้อผิดพลาดในการออกแบบนี้เนื่องจากการเปลี่ยนลำดับชั้นการสืบทอดตอนนี้จะทำลายความเข้ากันได้กับรหัสที่มีอยู่ มีStackองค์ประกอบที่ใช้แทนการรับมรดกก็จะสามารถปรับเปลี่ยนการใช้โครงสร้างข้อมูลอื่นโดยไม่ละเมิดของ API

ฉันขอแนะนำหนังสือของ Josh Bloch Effective Java 2nd Edition

  • รายการที่ 16: การประพันธ์ชอบมากกว่าการสืบทอด
  • รายการที่ 17: การออกแบบและเอกสารสำหรับการสืบทอดไม่เช่นนั้นจะห้าม

การออกแบบเชิงวัตถุที่ดีนั้นไม่เกี่ยวกับการขยายคลาสที่มีอยู่อย่างอิสระ สัญชาตญาณแรกของคุณควรจะแต่งแทน


ดูสิ่งนี้ด้วย:


4
น่าสนใจ ทำไมไม่สร้างคลาส java.util.Stack2 ใหม่ที่ใช้การแต่งเพลง
qed

5
ฉันขอขอบคุณคำตอบนี้ อย่างไรก็ตามฉันรู้สึกราวกับว่าคำตอบหลุดออกไปและนำเสนอความกังวลเพิ่มเติมเกี่ยวกับการออกแบบภาษา (และแพ็คเกจเฉพาะ) มากกว่าที่จะตอบคำถามที่ถามเกี่ยวกับการแต่งเพลงกับการถ่ายทอดทางพันธุกรรม ฉันเป็นแฟนตัวยงของการตอบคำถามเกี่ยวกับ SO โดยอ้างถึงแหล่งข้อมูล - ไม่เชื่อมโยงไปยังแหล่งข้อมูลภายนอกโดยไม่ได้ให้ข้อมูลสรุปเชิงลึกมากกว่าการสรุปแบบบรรทัดเดียว
โธมัส

5
ตัวอย่างที่ไม่ดีฉันต้องทำการค้นหาเพิ่มเติมเพื่อทำความเข้าใจว่า Vector และ Stack คืออะไร
Sam Ramezanli

ดี แต่ตัวอย่างของคุณเกี่ยวกับจาวาสแต็กไม่ใช่ตัวเลือกที่ดีเพราะการสืบทอดนี้เป็นตัวอย่างของการตัดสินใจที่ไม่ดีเกี่ยวกับการเลือกการสืบทอดมากกว่าองค์ประกอบตามที่กล่าวไว้ในบทความนี้: thinkworks.com/insights/blog/ …
QMaster

212

องค์ประกอบหมายถึงHAS A
มรดกหมายความว่าIS A

Example: รถยนต์มีเครื่องยนต์และรถยนต์เป็นรถยนต์

ในการเขียนโปรแกรมนี้จะแสดงเป็น:

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
ฉันจะเปลี่ยน "รถยนต์" เป็น "ยานพาหนะที่ขับเคลื่อน" เช่นเดียวกับในรถยนต์และรถยนต์ที่มี interpratations ที่เทียบเท่ากัน
nanofarad

5
@hexafraction ฉันยอมรับว่ายานพาหนะน่าจะเป็นทางเลือกที่ดีกว่า แต่ในขณะเดียวกัน -codaddict- ได้แสดงจุดที่ดีสำหรับสิ่งที่ถูกถาม
nckbrz

5
"an engine":-/
Omar Tariq

หมดอายุอย่างสวยงาม +1 อ่านเพิ่มเติมjavarevisited.blogspot.in/2015/06/…
roottraveller

@AndreyAkhmetov Automobile สามารถมีtypeประเภทของสนามEnum
Ojonugwa Jude Ochalifu

42

การรับมรดกอาจเป็นอันตรายได้อย่างไร?

ลองยกตัวอย่าง

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

1) ตามที่ชัดเจนในโค้ดด้านบนคลาส Y มีเพศสัมพันธ์ที่แข็งแกร่งมากกับคลาส X หากมีการเปลี่ยนแปลงอะไรในซูเปอร์คลาส X, Y อาจแตกสลายอย่างมาก สมมติว่าในคลาส X ในอนาคตใช้วิธีการทำงานกับลายเซ็นด้านล่าง

public int work(){
}

การเปลี่ยนแปลงเสร็จสิ้นในคลาส X แต่จะทำให้คลาส Y ไม่สามารถทำงานได้ ดังนั้นการพึ่งพาแบบนี้สามารถขึ้นไปถึงระดับใดก็ได้และมันอาจเป็นอันตรายมาก ทุกครั้งที่ซูเปอร์คลาสอาจไม่สามารถมองเห็นโค้ดภายในคลาสย่อยและคลาสย่อยทั้งหมดได้อาจสังเกตเห็นสิ่งที่เกิดขึ้นในซูเปอร์คลาสตลอดเวลา ดังนั้นเราจึงต้องหลีกเลี่ยงการแต่งงานที่แข็งแกร่งและไม่จำเป็นนี้

การเรียบเรียงจะแก้ปัญหานี้อย่างไร

ให้ดูด้วยการแก้ไขตัวอย่างเดียวกัน

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

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

ที่นี่เรากำลังสร้างการอ้างอิงของคลาส X ในคลาส Y และวิธีการเรียกใช้ของคลาส X โดยการสร้างอินสแตนซ์ของคลาส X ตอนนี้การมีเพศสัมพันธ์ที่แข็งแกร่งก็หมดไป Superclass และ subclass มีความเป็นอิสระสูงต่อกัน คลาสสามารถเปลี่ยนแปลงได้อย่างอิสระซึ่งเป็นอันตรายในสถานการณ์การสืบทอด

2) ข้อได้เปรียบที่ดีมากอย่างที่สองของการจัดวางในนั้นจะให้วิธีการเรียกความยืดหยุ่นตัวอย่างเช่น:

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

public class Test{    
    R r;    
}

ในคลาสทดสอบโดยใช้การอ้างอิง r ฉันสามารถเรียกใช้เมธอดของคลาส X และคลาส Y ได้ ความยืดหยุ่นนี้ไม่เคยมีในมรดก

3) ข้อได้เปรียบที่ยอดเยี่ยมอีกอย่างหนึ่ง: การทดสอบหน่วย

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

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

ในตัวอย่างข้างต้นหากไม่ทราบสถานะของอินสแตนซ์ x สามารถจำลองได้อย่างง่ายดายโดยใช้ข้อมูลทดสอบและวิธีการทั้งหมดสามารถทดสอบได้อย่างง่ายดาย สิ่งนี้เป็นไปไม่ได้เลยในการสืบทอดเนื่องจากคุณต้องพึ่งพาซุปเปอร์คลาสมากเพื่อรับสถานะของอินสแตนซ์และดำเนินการวิธีการใด ๆ

4) อีกเหตุผลที่ดีที่เราควรหลีกเลี่ยงการสืบทอดคือ Java ไม่รองรับการสืบทอดหลายอย่าง

ให้ยกตัวอย่างเพื่อทำความเข้าใจสิ่งนี้:

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

ดีแล้วที่รู้ :

  1. การจัดวางสามารถทำได้อย่างง่ายดายในขณะที่การสืบทอดให้คุณสมบัติของมันในเวลารวบรวม

  2. องค์ประกอบยังเป็นที่รู้จักกันในนามของความสัมพันธ์ HAS-A และการถ่ายทอดทางพันธุกรรมยังเป็นที่รู้จักกันในนามความสัมพันธ์ IS-A

ดังนั้นทำให้มันเป็นนิสัยของการเลือกองค์ประกอบมากกว่าการสืบทอดด้วยเหตุผลต่าง ๆ ข้างต้น


3
เห็นด้วย แต่ให้วิธีแก้ปัญหาของคุณโดยใช้การประพันธ์ ... เรายังคงต้องทำ babysit เช่นตอนนี้ super class X เปลี่ยนชื่อวิธีจาก do เป็นทำ .... จากนั้นคลาสย่อย Y ก็จะต้องได้รับการดูแลด้วย เช่นกัน) นี่คือการมีเพศสัมพันธ์อย่างแน่นหนาเหรอ? และเราจะกำจัดมันได้อย่างไร
stickedoverflow

19

คำตอบที่ @Michael Rodrigues ไม่ถูกต้อง (ฉันขอโทษฉันไม่สามารถแสดงความคิดเห็นโดยตรง) และอาจนำไปสู่ความสับสน

การใช้อินเตอร์เฟสเป็นรูปแบบของการสืบทอด ... เมื่อคุณใช้อินเตอร์เฟสคุณไม่เพียง แต่สืบทอดค่าคงที่ทั้งหมดเท่านั้น แต่ยังทำให้วัตถุของคุณเป็นประเภทที่ระบุโดยอินเตอร์เฟส มันยังคงเป็นความสัมพันธ์แบบ" is-a " หากรถใช้fillableรถ " เป็นแบบ " fillableและสามารถนำมาใช้ในรหัสของคุณทุกที่ที่คุณจะใช้fillable

องค์ประกอบเป็นพื้นฐานแตกต่างจากมรดก เมื่อคุณใช้องค์ประกอบที่คุณมี (เป็นคำตอบอื่น ๆ ทราบ) การทำ " มี-A " ความสัมพันธ์ระหว่างวัตถุสองเมื่อเทียบกับ " เป็นแบบ " ความสัมพันธ์ที่คุณทำเมื่อคุณใช้มรดก

ดังนั้นจากตัวอย่างรถยนต์ในคำถามอื่น ๆ ถ้าผมอยากจะบอกว่ารถ " มี-A " ถังแก๊สผมจะใช้องค์ประกอบดังต่อไปนี้:

public class Car {

private GasTank myCarsGasTank;

}

หวังว่าจะช่วยขจัดความเข้าใจผิด ๆ


17

การรับมรดกนำความสัมพันธ์IS-Aออกมา องค์ประกอบนำเสนอความสัมพันธ์ HAS-Aออกมา รูปแบบกลยุทธ์อธิบายว่าควรใช้องค์ประกอบในกรณีที่มีตระกูลของอัลกอริทึมที่กำหนดพฤติกรรมเฉพาะ
ตัวอย่างคลาสสิกเป็นของคลาสเป็ดซึ่งใช้พฤติกรรมการบิน

public interface Flyable{
 public void fly();
}

public class Duck {
 Flyable fly;

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

ดังนั้นเราสามารถมีหลายคลาสที่ใช้การบินเช่น:

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");
  }
}

หากเป็นมรดกเราจะมีนกสองประเภทที่แตกต่างกันซึ่งใช้ฟังก์ชั่นการบินซ้ำแล้วซ้ำอีก ดังนั้นการถ่ายทอดและองค์ประกอบจึงแตกต่างอย่างสิ้นเชิง


7

การประพันธ์เป็นเหมือนเสียง - คุณสร้างวัตถุโดยเสียบชิ้นส่วน

แก้ไขส่วนที่เหลือของคำตอบนี้เป็นไปตามที่ตั้งไว้อย่างไม่ถูกต้อง
นี่คือความสำเร็จด้วยอินเทอร์เฟซ
ตัวอย่างเช่นใช้Carตัวอย่างด้านบน

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

ดังนั้นด้วยองค์ประกอบทางทฤษฎีมาตรฐานเล็กน้อยคุณสามารถสร้างวัตถุของคุณ จากนั้นเป็นหน้าที่ของคุณในการเติมเต็มว่าผู้Houseปกป้องคุ้มครองผู้โดยสารอย่างไรและCarปกป้องผู้ขับขี่อย่างไร

การรับมรดกเป็นเหมือนวิธีอื่น ๆ คุณเริ่มต้นด้วยวัตถุสมบูรณ์ (หรือกึ่งสมบูรณ์) และคุณแทนที่หรือแทนที่บิตต่าง ๆ ที่คุณต้องการเปลี่ยน

ตัวอย่างเช่นMotorVehicleอาจมาพร้อมกับFuelableวิธีการและDriveวิธีการ คุณอาจจะออกจากวิธีเชื้อเพลิงมันเป็นเพราะมันเป็นเรื่องเดียวที่จะเติมรถมอเตอร์ไซด์และรถ แต่คุณอาจแทนที่วิธีการเพราะไดรฟ์รถมอเตอร์ไซด์แตกต่างกันมากไปDriveCar

ด้วยการสืบทอดบางคลาสจะถูกนำไปใช้อย่างสมบูรณ์แล้วและบางคลาสมีวิธีการที่คุณถูกบังคับให้แทนที่ ด้วย Composition ไม่มีอะไรที่มอบให้คุณ (แต่คุณสามารถใช้อินเทอร์เฟซได้โดยการเรียกเมธอดในคลาสอื่นถ้าคุณมีบางอย่างวางทับ)

องค์ประกอบถูกมองว่ามีความยืดหยุ่นมากขึ้นเพราะถ้าคุณมีวิธีการเช่น iUsesFuel คุณสามารถมีวิธีอื่น (คลาสอื่นอีกโครงการหนึ่ง) ที่กังวลเกี่ยวกับการจัดการกับวัตถุที่สามารถเติมเชื้อเพลิงได้โดยไม่คำนึงว่าเป็นรถยนต์หรือไม่ เรือเตาบาร์บีคิว ฯลฯ อินเทอร์เฟซอาณัติว่าคลาสที่กล่าวว่าพวกเขาใช้อินเทอร์เฟซนั้นจริง ๆ แล้วมีวิธีการที่อินเทอร์เฟซนั้นเป็นข้อมูลเกี่ยวกับ ตัวอย่างเช่น,

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

จากนั้นคุณสามารถมีวิธีการอื่น

private void FillHerUp(iFuelable : objectToFill) {

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

        objectToFill.AddSomeFuel();
   }

ตัวอย่างที่แปลก แต่ก็แสดงให้เห็นว่าวิธีนี้ไม่สนใจสิ่งที่มันเติมเพราะวัตถุใช้iUsesFuelมันสามารถเติมได้ ตอนจบของเรื่อง.

หากคุณใช้ Inheritance แทนคุณจะต้องใช้FillHerUpวิธีการที่แตกต่างกันในการจัดการMotorVehiclesและBarbecuesยกเว้นว่าคุณมีวัตถุพื้นฐาน "ObjectThatUsesFuel" ที่ค่อนข้างแปลก ๆ


Java รัฐอนุสัญญาว่าชื่อชั้นเรียนและอินเตอร์เฟซจะถูกเขียนในไม่ได้อยู่ในThisCase camelCaseดังนั้นจึงเป็นการดีที่สุดที่จะตั้งชื่ออินเทอร์เฟซของคุณIDrivableฯลฯ คุณอาจไม่จำเป็นต้องมี "ฉัน" หากคุณจัดกลุ่มอินเทอร์เฟซทั้งหมดของคุณใหม่ให้เป็นแพคเกจที่ถูกต้อง
ThePyroEagle

6

องค์ประกอบและมรดกมีเหมือนกันหรือไม่?

พวกเขาไม่เหมือนกัน

องค์ประกอบ : มันช่วยให้กลุ่มของวัตถุจะต้องได้รับการปฏิบัติในลักษณะเดียวกับอินสแตนซ์เดียวของวัตถุ ความตั้งใจของคอมโพสิตคือการ "เขียน" วัตถุลงในโครงสร้างต้นไม้เพื่อเป็นตัวแทนของลำดับชั้นส่วนทั้งหมด

การสืบทอด : คลาสสืบทอดฟิลด์และเมธอดจากซูเปอร์คลาสทั้งหมดไม่ว่าโดยตรงหรือโดยอ้อม คลาสย่อยสามารถแทนที่เมธอดที่สืบทอดหรือสามารถซ่อนฟิลด์หรือเมธอดที่สืบทอด

หากฉันต้องการใช้รูปแบบการแต่งเพลงฉันจะทำสิ่งนั้นใน Java ได้อย่างไร

บทความWikipediaนั้นดีพอที่จะใช้รูปแบบคอมโพสิตใน java

ป้อนคำอธิบายรูปภาพที่นี่

ผู้เข้าร่วมที่สำคัญ:

ส่วนประกอบ :

  1. เป็นนามธรรมของส่วนประกอบทั้งหมดรวมถึงคอมโพสิต
  2. ประกาศส่วนต่อประสานสำหรับวัตถุในองค์ประกอบ

ใบไม้ :

  1. แสดงให้เห็นถึงวัตถุใบไม้ในองค์ประกอบ
  2. ใช้วิธีการส่วนประกอบทั้งหมด

คอมโพสิต :

  1. แสดงให้เห็นถึงส่วนประกอบคอมโพสิต (ส่วนประกอบที่มีลูก ๆ )
  2. ใช้วิธีการจัดการเด็ก
  3. ใช้วิธีการส่วนประกอบทั้งหมดโดยทั่วไปโดยมอบหมายให้เด็ก ๆ

ตัวอย่างโค้ดที่จะเข้าใจรูปแบบคอมโพสิต :

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());
    }

}

เอาท์พุท:

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

คำอธิบาย:

  1. ส่วนที่เป็นใบ
  2. รถยนต์มีหลายส่วน
  3. เพิ่มส่วนต่าง ๆของรถลงในรถแล้ว
  4. ราคารถยนต์ = ผลรวมของ (ราคาของแต่ละส่วน )

อ้างถึงคำถามด้านล่างสำหรับข้อดีข้อเสียขององค์ประกอบและการสืบทอด

ชอบการแต่งมากกว่าการสืบทอด?


มันสมเหตุสมผลไหมที่จะใช้ชิ้นส่วนสำหรับคลาสรถยนต์ด้วย มันจะไม่ดีถ้าคุณใช้มันเป็นองค์ประกอบ
bhalkian

4

เป็นอีกตัวอย่างหนึ่งให้พิจารณารถคลาสนี่จะเป็นการใช้องค์ประกอบที่ดีรถยนต์จะ "มี" เครื่องยนต์เกียร์ยางที่นั่ง ฯลฯ มันจะไม่ขยายชั้นเรียนเหล่านั้น


4

การจัดองค์ประกอบเป็นสิ่งที่ประกอบไปด้วยชิ้นส่วนที่แตกต่างกันและมีความสัมพันธ์ที่แน่นแฟ้นกับชิ้นส่วนเหล่านั้น หากส่วนหลักตายไปผู้อื่นก็ทำเช่นนั้นพวกเขาไม่สามารถมีชีวิตของตนเองได้ ตัวอย่างคร่าวๆคือร่างกายมนุษย์ ออกไปจากหัวใจและส่วนอื่น ๆ ทั้งหมดจะตายไป

การรับมรดกเป็นที่ที่คุณเพียงนำสิ่งที่มีอยู่แล้วมาใช้ ไม่มีความสัมพันธ์ที่แข็งแกร่ง คน ๆ หนึ่งสามารถสืบทอดมรดกที่ดินของเขา แต่เขาสามารถทำได้โดยปราศจากมัน

ฉันไม่รู้ Java ดังนั้นฉันจึงไม่สามารถให้ตัวอย่าง แต่ฉันสามารถให้คำอธิบายเกี่ยวกับแนวคิด


3

การสืบทอด ระหว่างสองคลาสโดยที่หนึ่งคลาสขยายคลาสอีกคลาสหนึ่งสร้างความสัมพันธ์" IS A "

องค์ประกอบในส่วนอื่น ๆ มีตัวอย่างของคลาสอื่นในชั้นเรียนของคุณสร้างความสัมพันธ์ " มี " องค์ประกอบใน java มีประโยชน์เนื่องจากช่วยอำนวยความสะดวกในการสืบทอดหลาย ๆ อย่างทางเทคนิค


3

ในการรวมคำง่าย ๆ หมายถึงมีความสัมพันธ์ ..

องค์ประกอบเป็นกรณีพิเศษของการรวม ในลักษณะที่เฉพาะเจาะจงมากขึ้นการรวมที่ถูก จำกัด เรียกว่าการรวม เมื่อวัตถุมีวัตถุอื่น ๆ ถ้าวัตถุที่มีอยู่ไม่สามารถอยู่ได้โดยปราศจากวัตถุภาชนะแล้วมันจะเรียกว่าองค์ประกอบ ตัวอย่าง: ชั้นเรียนมีนักเรียน นักเรียนไม่สามารถอยู่ได้โดยปราศจากชั้นเรียน มีการจัดองค์ประกอบระหว่างชั้นเรียนและนักเรียน

ทำไมต้องใช้การรวม

การใช้รหัสซ้ำ

เมื่อใช้การรวม

การนำรหัสกลับมาใช้ใหม่ทำได้โดยการรวมกันเมื่อไม่มีการจัดส่งที่เกี่ยวข้อง

มรดก

การสืบทอดเป็นความสัมพันธ์ของผู้ปกครองเด็กการถ่ายทอดความหมายหมายถึงเป็นความสัมพันธ์

การสืบทอดใน java เป็นกลไกที่วัตถุหนึ่งได้รับคุณสมบัติและพฤติกรรมทั้งหมดของวัตถุแม่

การใช้การสืบทอดในการใช้รหัส Java 1 2 เพิ่มคุณสมบัติพิเศษในคลาสเด็กเช่นเดียวกับการเอาชนะเมธอด


1

แม้ว่าทั้ง Inheritance และ Composition จะให้ reusablility ของรหัส แต่ความแตกต่างที่สำคัญระหว่าง Composition และ Inheritance ใน Java ก็คือ Composition จะอนุญาตให้นำโค้ดกลับมาใช้ใหม่ได้โดยไม่ต้องขยาย แต่สำหรับ Inheritance คุณจะต้องขยายคลาสเพื่อนำโค้ด ความแตกต่างอีกอย่างที่มาจากความจริงข้อนี้คือการใช้ Composition คุณสามารถนำโค้ดกลับมาใช้ใหม่ได้แม้กระทั่งคลาสสุดท้ายที่ไม่สามารถขยายได้ แต่การสืบทอดไม่สามารถนำโค้ดกลับมาใช้ใหม่ได้ในกรณีเช่นนี้ นอกจากนี้โดยใช้ Composition คุณสามารถนำโค้ดจากหลาย ๆ คลาสมาใช้ใหม่ได้เนื่องจากมีการประกาศว่าเป็นเพียงตัวแปรสมาชิก แต่ด้วย Inheritance คุณสามารถนำรหัสรูปแบบมาใช้ใหม่ได้เพียงคลาสเดียวเพราะใน Java คุณสามารถขยายได้หนึ่งคลาสเท่านั้น . คุณสามารถทำสิ่งนี้ใน C ++ ได้เนื่องจากมีหนึ่งคลาสสามารถขยายได้มากกว่าหนึ่งคลาส BTW คุณควรจะเสมอชอบองค์ประกอบมากกว่ามรดกใน Javaมันไม่ได้เป็นเพียงฉัน แต่โจชัวโบลชได้แนะนำในหนังสือของเขา


1
เหตุใดฉันจึงควร " เรียงความองค์ประกอบเหนือมรดก " พวกเขาเป็นแนวคิดที่แตกต่างและใช้เพื่อวัตถุประสงค์ที่แตกต่างกัน ตรงไปตรงมาฉันไม่เห็นว่าคุณจะไปจากที่หนึ่งไปยังอีก
Kröw

1

ผมคิดว่าตัวอย่างนี้อธิบายได้อย่างชัดเจนความแตกต่างระหว่างการรับมรดกและองค์ประกอบ

ใน exmple นี้ปัญหาได้รับการแก้ไขโดยใช้การสืบทอดและองค์ประกอบ ผู้เขียนให้ความสนใจกับความจริงที่ว่า; ในการสืบทอดการเปลี่ยนแปลงในซูเปอร์คลาสอาจทำให้เกิดปัญหาในคลาสที่ได้รับซึ่งสืบทอดมา

คุณสามารถเห็นความแตกต่างในการเป็นตัวแทนเมื่อคุณใช้ UML สำหรับการสืบทอดหรือการแต่งเพลง

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


1
ลิงก์คำตอบเท่านั้นที่หมดกำลังใจเพราะพวกเขาไปค้าง โปรดระบุข้อมูลที่เกี่ยวข้องที่สำคัญที่สุดอย่างน้อยจากลิงก์ในคำตอบของคุณ
Scott Solmer

1

Inheritances Vs Composition

การสืบทอดและการจัดองค์ประกอบทั้งสองถูกใช้เพื่อการใช้งานใหม่และการขยายพฤติกรรมของคลาส

มรดกส่วนใหญ่ใช้ในรูปแบบการเขียนโปรแกรมอัลกอริทึมตระกูลเช่นประเภทความสัมพันธ์ IS-A หมายถึงวัตถุชนิดเดียวกัน ตัวอย่าง.

  1. Duster เป็นรถยนต์
  2. Safari คือรถยนต์

เหล่านี้เป็นของครอบครัว Car

องค์ประกอบแสดงถึงประเภทความสัมพันธ์ HAS-A มันแสดงความสามารถของวัตถุเช่น Duster มี Five Gears, Safari มีสี่ Gears เป็นต้นเมื่อใดก็ตามที่เราต้องการที่จะขยายความสามารถของคลาสที่มีอยู่แล้วใช้องค์ประกอบ ตัวอย่างเราต้องเพิ่มอีกหนึ่งเกียร์ในวัตถุ Duster แล้วเราต้องสร้างอีกหนึ่งวัตถุเกียร์และเขียนไปยังวัตถุแปรง

เราไม่ควรทำการเปลี่ยนแปลงในคลาสฐานจนกว่า / เว้นแต่คลาสที่ได้รับทั้งหมดต้องการฟังก์ชันเหล่านั้นสำหรับสถานการณ์นี้เราควรใช้ Composition เช่น

class A มาจาก Class B

Class A มาจาก Class C

Class A มาจาก Class D

เมื่อเราเพิ่มฟังก์ชั่นใด ๆ ในคลาส A ดังนั้นคลาสย่อยทั้งหมดจะสามารถใช้งานได้แม้ว่า Class C และ D จะไม่ต้องการฟังก์ชันเหล่านั้นสำหรับสถานการณ์นี้เราต้องสร้างคลาสแยกต่างหากสำหรับฟังก์ชั่นเหล่านั้นและเขียนลงในคลาสที่ต้องการ นี่คือคลาส B)

ด้านล่างเป็นตัวอย่าง:

          // 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

องค์ประกอบหมายถึงการสร้างวัตถุให้กับคลาสที่มีความสัมพันธ์กับคลาสนั้น ๆ สมมติว่านักเรียนมีความสัมพันธ์กับบัญชี

Inheritance คือนี่เป็นคลาสก่อนหน้าพร้อมกับคุณสมบัติเพิ่มเติม นั่นหมายถึงคลาสใหม่นี้เป็นคลาสเก่าที่มีคุณสมบัติเพิ่มเติมบางอย่าง สมมติว่านักเรียนเป็นนักเรียน แต่นักเรียนทุกคนเป็นมนุษย์ ดังนั้นจึงมีความสัมพันธ์กับนักเรียนและมนุษย์ นี่คือมรดก


0

ไม่ทั้งสองแตกต่างกัน องค์ประกอบติดตามความสัมพันธ์ "HAS-A" และการสืบทอดตามความสัมพันธ์ "IS-A" ตัวอย่างที่ดีที่สุดสำหรับการจัดองค์ประกอบคือรูปแบบเชิงกลยุทธ์


2
คุณภาพความคิดเห็นเท่านั้น
Mathews Sunny

คุณเพิ่งแสดงความคิดเห็นแบบเดียวกันกับที่คำตอบที่ยอมรับได้กล่าวไว้เมื่อ 7 ปีก่อนใช่ไหม?
Anjil Dhamala

0

Inheritence หมายถึงการนำฟังก์ชั่นที่สมบูรณ์ของคลาสกลับมาใช้ใหม่ที่นี่ชั้นเรียนของฉันต้องใช้วิธีการทั้งหมดของซุปเปอร์คลาสและคลาสของฉันจะถูกผนวกเข้ากับคลาสซูเปอร์อย่างแน่นหนาและรหัสจะซ้ำกันทั้งสองคลาสในกรณีสืบทอด

แต่เราสามารถเอาชนะปัญหาเหล่านี้ได้เมื่อเราใช้การประพันธ์เพื่อพูดคุยกับชั้นเรียนอื่น การเรียบเรียงคือการประกาศคุณลักษณะของชั้นเรียนอื่นในชั้นเรียนของฉันที่เราต้องการพูดคุย และฟังก์ชั่นที่เราต้องการจากคลาสนั้นเราสามารถทำได้โดยใช้คุณสมบัตินั้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.