ฉันต้องการมีคลาสวัตถุ แต่ฉันต้องการบังคับให้คลาสใดก็ตามที่แสดงถึงการขยายคลาส A และใช้อินเตอร์เฟส B
ที่ฉันสามารถทำได้:
Class<? extends ClassA>
หรือ:
Class<? extends InterfaceB>
แต่ฉันทำทั้งสองอย่างไม่ได้ มีวิธีทำเช่นนี้หรือไม่?
ฉันต้องการมีคลาสวัตถุ แต่ฉันต้องการบังคับให้คลาสใดก็ตามที่แสดงถึงการขยายคลาส A และใช้อินเตอร์เฟส B
ที่ฉันสามารถทำได้:
Class<? extends ClassA>
หรือ:
Class<? extends InterfaceB>
แต่ฉันทำทั้งสองอย่างไม่ได้ มีวิธีทำเช่นนี้หรือไม่?
คำตอบ:
ที่จริงคุณสามารถทำสิ่งที่คุณต้องการ ถ้าคุณต้องการให้หลาย ๆ อินเทอร์เฟซหรือคลาสบวกอินเทอร์เฟซคุณต้องให้ตัวแทนของคุณมีลักษณะดังนี้:
<T extends ClassA & InterfaceB>
ดูบทช่วยสอนทั่วไปที่ sun.com โดยเฉพาะอย่างยิ่งในส่วนพารามิเตอร์ชนิดที่ถูกผูกไว้ที่ด้านล่างของหน้า คุณสามารถแสดงรายการอินเทอร์เฟซได้มากกว่าหนึ่งรายการหากต้องการโดยใช้& InterfaceName
สำหรับแต่ละรายการที่คุณต้องการ
สิ่งนี้อาจมีความซับซ้อนตามอำเภอใจ ในการสาธิตให้ดูที่การประกาศ JavaDoc Collections#max
ซึ่ง (ห่อลงบนสองบรรทัด) คือ:
public static <T extends Object & Comparable<? super T>> T
max(Collection<? extends T> coll)
ทำไมจึงซับซ้อน ตามที่กล่าวใน Java Generics คำถามที่พบบ่อย: เพื่อรักษาความเข้ากันได้แบบไบนารี
ดูเหมือนว่าสิ่งนี้จะไม่ทำงานสำหรับการประกาศตัวแปร แต่มันจะทำงานเมื่อใส่ขอบเขตทั่วไปในชั้นเรียน ดังนั้นในการทำสิ่งที่คุณต้องการคุณอาจต้องกระโดดข้ามห่วงไปสองสามครั้ง แต่คุณสามารถทำได้ คุณสามารถทำสิ่งนี้วางขอบเขตทั่วไปในชั้นเรียนของคุณแล้ว:
class classB { }
interface interfaceC { }
public class MyClass<T extends classB & interfaceC> {
Class<T> variable;
}
เพื่อให้ได้variable
ข้อ จำกัด ที่คุณต้องการ สำหรับข้อมูลเพิ่มเติมและตัวอย่างการตรวจสอบหน้า 3 ของGenerics ในชวา 5.0 หมายเหตุใน<T extends B & C>
ชื่อคลาสจะต้องมาก่อนและอินเทอร์เฟซตาม และแน่นอนว่าคุณสามารถแสดงคลาสได้เพียงรายการเดียวเท่านั้น
?
ในนิพจน์นั้นดังนั้นจึงเป็น "อักขระตัวแทน" จริง ๆ หรือ ฉันถามเพราะฉันไม่สามารถรับแนวคิด "การขยายสองสิ่งในคราวเดียว" ทั้งหมดเพื่อให้ทำงานได้เมื่อพารามิเตอร์ประเภทเป็นสัญลักษณ์แทน
คุณไม่สามารถทำได้ด้วยพารามิเตอร์ประเภท "ไม่ระบุชื่อ" (เช่นสัญลักษณ์ตัวแทนที่ใช้?
) แต่คุณสามารถทำได้ด้วยพารามิเตอร์ประเภท "ชื่อ" เพียงประกาศพารามิเตอร์ประเภทที่วิธีหรือระดับชั้นเรียน
import java.util.List;
interface A{}
interface B{}
public class Test<E extends B & A, T extends List<E>> {
T t;
}