Base
ฉันได้เรียนฐาน มันมีอยู่สอง subclasses, และSub1
Sub2
แต่ละคลาสย่อยมีวิธีเพิ่มเติมบางอย่าง ตัวอย่างเช่นSub1
มีSandwich makeASandwich(Ingredients... ingredients)
และมีSub2
boolean 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
ไม่สามารถใช้แทนกันได้ทำไมคุณปฏิบัติต่อพวกเขาเช่นนี้? ทำไมไม่ติดตาม 'ผู้สร้างแซนวิช' และ 'ผู้ติดต่อกับคนต่างด้าว' แยกกันล่ะ