[英]In Java, can I somehow move field to superclass if subclasses have different types for them?
在我的Java程序中,我有兩個真正相似的類,因此為它們創建一個超類以將其子類化並推廣一堆方法將非常有意義。
唯一的問題是,它們的關鍵字段之一是作為Queue
實現的,而一個字段是PriorityQueue
。
有什么方法可以超類化這些類並以某種方式泛化字段類型,並讓子類選擇在實例化時可能會做什么?
public Base{
}
public Sub1{
Queue<Customer> customers;
}
public Sub2{
PriorityQueue<Customer> customers;
}
priorityqueue是實現隊列的抽象隊列的子類,因此基本隊列可以有一個客戶隊列。
你需要做的是有排隊customers
作為一個依賴Base
,讓客戶端代碼決定什么排隊實例。
public Base{
private Queue<Customer> customers;
protected Base(Queue<Customer> customers) {
this.queue = queue;
}
}
您不需要Sub1
和Sub2
類,因為它們僅在使用的隊列方面不同於Base
。 客戶代碼可以簡單地決定使用哪個隊列:
Base baseWithQueue = new Base(new ArrayBlockingQueue<Customer>());
Base baseWithPriorityQueue = new Base(new PriorirityQueue<Customer>());
PriorityQueue
類實現了Queue
接口,所以我建議將Base
作為抽象類,並在其中保留customers
集合( Queue
類型)。 然后根據需要從Sub1
或Sub2
的構造函數實例化customers
。
是的,因為PriorityQueue
實現了Queue
。 如果要將創建委托給子類,請讓它們將適當的Queue
傳遞給基本構造函數使用:
public class Base {
protected final Queue<Customer> customers;
protected Base(Queue<Customer> c) {
this.customers = c;
}
}
public class Sub1 extends Base {
Sub1() {
super(new WhateverQueue<Customer>());
}
}
public class Sub2 extends Base {
Sub2() {
super(new PriorityQueue<Customer>());
}
}
我應該提到,如果Sub2
需要在某些特定於Sub2
方法中使用特定於PriorityQueue
(例如comparator
),則可以:
強制轉換customers
(因為它知道customers
實際上是PriorityQueue<Customer>
,而不僅僅是Queue<Customer>
),或者
聲明自己的實例字段,該實例字段將保留鍵入的引用:
private PriorityQueue<Customer> priorityCustomers; Sub2() { super(new PriorityQueue<Customer>()); this.priorityCustomers = (PriorityQueue<Customer>)(this.customers); }
#2使所需的轉換保持在最低限度,並且僅包含在構造函數中,可以輕松地將PriorityQueue<Customer>
更改為其他內容。
是的,如果將字段實現為Queue
,則可以在Sub2
中將其實例化為PriorityQueue
,因為PriorityQueue
實現了Queue
(來源: http : //docs.oracle.com/javase/7/docs/api/java/util/ PriorityQueue.html )
public Base{
Queue<Customer> customers;
public Base(Queue<Customers> queue){
this.customers = queue;
}
}
public Sub1{
public Sub1(){
super(new Queue<Customer>());
}
}
public Sub2{
public Sub2(){
super(new PriorityQueue<Customer>());
}
}
但是,當您需要將customers
字段用作Sub2
內的PriorityQueue
(而不是Queue
)時,需要將其Sub2
轉換為PriorityQueue
。
一種解決方案是為customers
屬性提供常規的Queue
類型,這將為您提供靈活性。 但是,如果您想在給定的子類中實施特定的實現,並在程序的其余部分中攜帶該信息,則可以使用通用約束:
public class Base<Q extends Queue<Customers>> {
protected Q customers;
public Base(Q customers) {
this.customers = customers;
}
}
public Sub1 extends Base<Queue<Customers>> {
public Sub1(Queue<String> customers) {
super(customers);
}
}
public Sub2 extends Base<PriorityQueue<Customers>>{
public Sub2() {
// Sub2 only supports PriorityQueues
super(new PriorityQueue<String>());
}
}
這很有用,因為它允許您在Sub2
內部調用,例如, customers.comparator()
,而無需將customers
轉換為PriorityQueue
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.