การพัฒนา Java โดยทั่วไปเกี่ยวข้องกับคลาสย่อยมากกว่า C # /. NET หรือไม่


34

ฉันเพิ่งเริ่มดูการพัฒนา Android สิ่งนี้นำฉันกลับสู่โลกของการพัฒนาซอฟต์แวร์ Java ครั้งสุดท้ายที่ฉันทำงานกับ Java ฉันจะยอมรับว่าฉันไม่เข้าใจ OOP เท่าที่ฉันคิดตอนนี้

หลังจากใช้งาน C # เป็นส่วนใหญ่ในอาชีพของฉันฉันสังเกตเห็นความแตกต่างที่น่าตกใจในการใช้ Java และ C # ในการสืบทอด

ใน C # ดูเหมือนว่าสามารถหลีกเลี่ยงการสืบทอดในสถานการณ์ส่วนใหญ่ งานในมือสามารถทำได้โดยใช้คลาสที่เป็นรูปธรรมของ. NET Framework

ใน Java จากสิ่งที่ฉันรวบรวมจากตัวอย่างโค้ดดูเหมือนว่า Java framework จะให้ส่วนต่อประสานหรือคลาสนามธรรมที่มีความหมายที่จะนำไปใช้ / ขยายโดยนักพัฒนา

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

นอกจากนี้ยังมีข้อ จำกัด เพียงแค่ Android SDK หรือนี่เป็นแนวทางแบบกว้าง ๆ ของ OOP หรือไม่?

หรือใส่ในอีกทางหนึ่ง

มันเกี่ยวกับการออกแบบของสองภาษานี้ที่ดูเหมือนว่าจะส่งเสริมให้ใช้มรดกมากกว่าหรือน้อยกว่าอีก?

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


1
มันเป็นความจริง. Java มีอินเตอร์เฟสมากเกินไป ฉันชอบที่จะรู้ว่าทำไมพฤติกรรมของนักพัฒนานี้จึงเป็นเรื่องปกติสำหรับภาษาใดภาษาหนึ่งโดยเฉพาะ ฉันเห็นสิ่งนี้เกิดขึ้นบ่อยครั้งในโครงการ Java มากกว่าสิ่งอื่นใด จะต้องมีเหตุผลสำหรับสิ่งนี้และไม่ใช่แค่ความเห็น
Reactgular

1
@MathewFoscarini ก็เพียงคุณมีความคิดเห็น ในโครงการ Java ที่ฉันเข้าร่วมผู้พัฒนามีแนวโน้มที่จะหลีกเลี่ยงการสืบทอดเช่นภัยพิบัติ ไม่มีอะไรเผด็จการที่นี่ของฉันเท่านั้นความคิดเห็น ต้องการสำรวจความคิดเห็น ?
ริ้น

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

1
@ThinkingMedia โดยทั่วไป Java มีค่าใช้จ่ายมากกว่า zealots / purists หลักการทางวิชาการเป็นเรื่องที่น่ากังวล นักพัฒนา. NET เป็นนักปฏิบัติที่มีความกังวลเกี่ยวกับการทำให้งานสำเร็จ พวกเขาให้ความสำคัญกับรหัสการทำงานมากกว่ารหัสที่สะอาดที่สุด
Andy

คำตอบ:


31

ดูเหมือนว่าจะมีความแตกต่างใหญ่เกินไปที่จะทำให้สไตล์ อะไรคือเหตุผลเบื้องหลังสิ่งนี้

ความเข้าใจของฉันก็คือว่ามันส่วนใหญ่เป็นเพียงการตัดสินใจโวหาร บางทีอาจไม่ใช่สไตล์ แต่เป็นสำนวนของภาษา / สภาพแวดล้อม ผู้พัฒนาไลบรารีมาตรฐานของจาวาได้ปฏิบัติตามแนวทางการออกแบบชุดหนึ่งและผู้พัฒนา. NET อีกคนหนึ่ง (แม้ว่าพวกเขาจะมีความสามารถในการดูว่าวิธีการของจาวาทำงานอย่างไร)

ในภาษาจริงมีน้อยมากที่จะสนับสนุนหรือห้ามการสืบทอด มีเพียงสองสิ่งที่ทำให้ฉันมีความเกี่ยวข้อง:

  1. .NET แนะนำ generics ก่อนหน้านี้ในช่วงชีวิตของพวกเขาก่อนที่จะใช้รหัสที่ไม่ใช่ทั่วไปมากเกินไป ทางเลือกคือความสามารถในการถ่ายทอดสิ่งต่าง ๆ มากมาย

  2. การเปลี่ยนแปลงที่ใหญ่กว่านั้นคือ. NET รองรับผู้ได้รับมอบหมาย ใน Java คุณติดอยู่กับการสืบทอด (ไม่ระบุชื่อ) เพื่อจัดหาฟังก์ชันพื้นฐานที่ผันแปรได้ สิ่งนี้นำไปสู่ความแตกต่างที่ค่อนข้างใหญ่ในวิธีที่รหัสถูกออกแบบมาเพื่อใช้ประโยชน์จากผู้ได้รับมอบหมายหรือเพื่อหลีกเลี่ยงโครงสร้างการสืบทอดที่น่าอึดอัดใจที่ต้องทำใน Java


3
ฉันคิดว่าคำตอบนี้มีคำอธิบายที่น่าเชื่อถือมาก โดยเฉพาะอย่างยิ่งจุดที่เกี่ยวกับมรดกที่ไม่ระบุชื่อแทนผู้ได้รับมอบหมาย ฉันสังเกตสิ่งนี้มาก ขอบคุณ
MetaFight

3
อย่าลืมประเภทนิรนามและต้นไม้แลมบ์ดาของไวยากรณ์ / นิพจน์ที่ถูกนำมาใช้ใน. NET 3.5 และแน่นอนว่าการเลือกใช้การพิมพ์แบบไดนามิกใน. NET 4 มันเป็นภาษาที่มีกระบวนทัศน์ผสมกันอยู่แล้วในตอนนี้ไม่ใช่เชิงวัตถุอย่างเคร่งครัด
Aaronaught

ใช่จากประสบการณ์ของฉันที่ใช้ทั้งสองอย่าง (รวมถึงโครงการผสมที่คนเดียวกันใช้ทั้งสองภาษา) คนมักจะชอบที่จะใช้คลาสที่เล็กกว่าจำนวนมากเมื่อเขียนโปรแกรม Java ซึ่งเป็นคลาสที่ใหญ่กว่า ใช้ C # เมื่อมีการสร้างต้นแบบโดยเจตนาโดยใช้สไตล์เดียวกันในทั้งสองอย่างคุณจะต้องจบด้วยจำนวนคลาสที่คล้ายกัน (โดยใช้คลาสบางส่วนคุณอาจท้ายด้วยไฟล์รหัสเพิ่มเติมแม้ในขณะที่ใช้ C #)
jwenting

6

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

ใน C # วิธีการพื้นฐานคือการตรวจสอบกิจกรรมต่างๆการตั้งค่าวิธีการที่จะดำเนินการเมื่อมีการเรียกใช้เหตุการณ์ที่น่าสนใจแต่ละเหตุการณ์ ใน Java ซึ่งขาดเหตุการณ์วิธีแก้ปัญหาตามปกติคือการส่งวัตถุด้วยวิธีการจัดการ "เหตุการณ์" ที่หลากหลายไปยังวิธี UIControl:

boolean  stillNeedIt =  ... ;
uiControl.whenSomethingHappens( new DoSomething()  {
    public void resized( Rectangle r )  { ... }
    public boolean canICloseNow()  { return !stillNeedIt; }
    public void closed()  { ... }
    ...
} );

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

นี่คือตัวอย่างไม่ใช่การอภิปรายที่ครอบคลุม แต่ให้ข้อมูลเบื้องต้นเกี่ยวกับสาเหตุที่มีการสืบทอดใน Java มากเมื่อเทียบกับ C #

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

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

public class BigClass implements DoSomething  {
    ...many long methods...
    protected int getDiameter()  { return 5; }
}

จากนั้นใน CleverlPanel:

uiControl.whenSomethingHappens( new BigClass()  {
    @Override
    public int getDiameter()  { return UIPanel.currentDiameter; }
} );

แพลตฟอร์ม Java แบบโอเพ่นซอร์สทำสิ่งนี้มากมายซึ่งมีแนวโน้มที่จะผลักดันให้โปรแกรมเมอร์ทำสิ่งต่างๆมากขึ้น - ทั้งคู่เพราะพวกเขาปฏิบัติตามเป็นตัวอย่างและเพื่อใช้งาน ฉันคิดว่าการออกแบบพื้นฐานของภาษาอยู่เบื้องหลังการออกแบบกรอบของ Sun และอยู่เบื้องหลังโปรแกรมเมอร์ Java ที่ใช้เทคนิคเมื่อไม่ได้ใช้กรอบงาน

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

(โปรดทราบว่าการใช้การสืบทอดขนาดใหญ่ที่นี่ - เช่นเดียวกับที่อื่นใน Java - นั้นใช้เพื่อวัตถุประสงค์ DRY เท่านั้นมันช่วยให้คลาสที่แตกต่างกันใช้รหัสเดียวกันซ้ำอีกครั้งโปรดสังเกตความง่ายในการสืบทอดใน Java )

นี่ไม่ใช่การอภิปรายที่ครอบคลุม ฉันแค่เกาที่นี่ แต่ใช่มีความแตกต่างที่น่าตกใจในวิธีการใช้การสืบทอดระหว่าง Java และ C # ในแง่นี้ภาษาต่างกันมาก ไม่ใช่จินตนาการของคุณ


หมายเหตุ: คุณสามารถหลีกเลี่ยงการให้วิธีการที่ไม่ทำอะไรเลยด้วยการขยายคลาสนามธรรมที่เต็มไปด้วยการใช้งานเปล่า วิธีนี้คุณสามารถเลือกแทนที่วิธีที่ทำบางสิ่งบางอย่าง แม้ว่าจะไม่น่าเกลียด แต่ก็หมายถึงการสืบทอดอีกระดับหนึ่ง
Peter Lawrey

-2

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

หวังว่าฉันช่วย!


5
คุณกำลังพูดถึงภาษาด้วยตัวเอง แต่ฉันคิดว่าคำถามนี้เกี่ยวกับห้องสมุดและการใช้งานทั่วไปด้วย
svick

3
แต่มีมีนิสัยใจคอในส่วนที่เหลือของภาษาที่ส่งเสริมให้เกิดการถ่ายทอดทางพันธุกรรมเป็นพิเศษในชวา; ดู RalphChapin ของคำตอบ
Izkata
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.