簡體   English   中英

在Java中,如果子類具有不同的類型,我可以以某種方式將字段移至超類嗎?

[英]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;
  }

}

您不需要Sub1Sub2類,因為它們僅在使用的隊列方面不同於Base 客戶代碼可以簡單地決定使用哪個隊列:

Base baseWithQueue = new Base(new ArrayBlockingQueue<Customer>());
Base baseWithPriorityQueue = new Base(new PriorirityQueue<Customer>());

PriorityQueue類實現了Queue接口,所以我建議將Base作為抽象類,並在其中保留customers集合( Queue類型)。 然后根據需要從Sub1Sub2的構造函數實例化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 ),則可以:

  1. 強制轉換customers (因為它知道customers實際上是PriorityQueue<Customer> ,而不僅僅是Queue<Customer> ),或者

  2. 聲明自己的實例字段,該實例字段將保留鍵入的引用:

     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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM