Baseฉันได้เรียนฐาน มันมีอยู่สอง subclasses, และSub1 Sub2แต่ละคลาสย่อยมีวิธีเพิ่มเติมบางอย่าง ตัวอย่างเช่นSub1มีSandwich makeASandwich(Ingredients... ingredients)และมีSub2boolean contactAliens(Frequency onFrequency)
เนื่องจากวิธีการเหล่านี้ใช้พารามิเตอร์ที่แตกต่างกันและทำสิ่งที่แตกต่างอย่างสิ้นเชิงพวกเขาไม่เข้ากันอย่างสมบูรณ์และฉันไม่สามารถใช้ความหลากหลายในการแก้ปัญหานี้ได้
Baseมอบการทำงานส่วนใหญ่และฉันมีBaseวัตถุจำนวนมาก อย่างไรก็ตามBaseวัตถุทั้งหมดเป็นแบบ a Sub1หรือ a Sub2และบางครั้งฉันจำเป็นต้องรู้ว่ามันคืออะไร
ดูเหมือนจะเป็นการดีที่จะทำสิ่งต่อไปนี้:
for (Base base : bases) {
if (base instanceof Sub1) {
((Sub1) base).makeASandwich(getRandomIngredients());
// ... etc.
} else { // must be Sub2
((Sub2) base).contactAliens(getFrequency());
// ... etc.
}
}
ดังนั้นฉันจึงคิดกลยุทธ์เพื่อหลีกเลี่ยงสิ่งนี้โดยไม่ต้องร่าย Baseตอนนี้มีวิธีการเหล่านี้:
boolean isSub1();
Sub1 asSub1();
Sub2 asSub2();
และแน่นอนSub1ใช้วิธีการเหล่านี้เป็น
boolean isSub1() { return true; }
Sub1 asSub1(); { return this; }
Sub2 asSub2(); { throw new IllegalStateException(); }
และSub2นำไปใช้ในทางตรงกันข้าม
น่าเสียดายที่ตอนนี้Sub1และSub2มีวิธีการเหล่านี้ใน API ของตัวเอง Sub1ดังนั้นผมจึงสามารถทำเช่นนี้เช่นบน
/** no need to use this if object is known to be Sub1 */
@Deprecated
boolean isSub1() { return true; }
/** no need to use this if object is known to be Sub1 */
@Deprecated
Sub1 asSub1(); { return this; }
/** no need to use this if object is known to be Sub1 */
@Deprecated
Sub2 asSub2(); { throw new IllegalStateException(); }
ด้วยวิธีนี้หากวัตถุเป็นที่รู้จักเพียง a Baseวิธีการเหล่านี้จะไม่เลิกใช้และสามารถใช้ในการ "cast" ตัวเองไปเป็นประเภทอื่นดังนั้นฉันจึงสามารถเรียกใช้เมธอด subclass ของมันได้ สิ่งนี้ดูสง่างามสำหรับฉัน แต่ในทางกลับกันฉันชอบใช้คำอธิบายประกอบที่ไม่เหมาะสมเป็นวิธี "ลบ" วิธีการออกจากชั้นเรียน
เนื่องจากSub1อินสแตนซ์จริงๆเป็น Base จึงเหมาะสมที่จะใช้การสืบทอดมากกว่าการห่อหุ้ม ฉันทำอะไรได้ดี มีวิธีที่ดีกว่าในการแก้ปัญหานี้หรือไม่?
instanceofในทางที่ต้องใช้จำนวนมากของการพิมพ์เป็นข้อผิดพลาดและทำให้มันยากที่จะเพิ่มมากขึ้น subclasses
Sub1และSub2ไม่สามารถใช้แทนกันได้ทำไมคุณปฏิบัติต่อพวกเขาเช่นนี้? ทำไมไม่ติดตาม 'ผู้สร้างแซนวิช' และ 'ผู้ติดต่อกับคนต่างด้าว' แยกกันล่ะ