2014-09-28 145 views
0

我被困在這個任務上。我給了一個抽象的Observer類,其中只有一個構造函數,它是一個帶參數/參數的構造函數。 (請參閱下面)觀察者模式類(JAVA)

public static void main(String[] args) {  
    PairOfNumbers numbers1 = new PairOfNumbers();    
    PairOfNumbers numbers2 = new PairOfNumbers();   
    SumObserver sum = new SumObserver(numbers1);   
    ProductObserver prod = new ProductObserver(numbers2);  
    MultiSubjectObserver m = new MultiSubjectObserver(); 
    m.addSubject(numbers1); 
    m.addSubject(numbers2);   
    numbers1.setNumbers(20, 10); 
    numbers2.setNumbers(-10, 15);  
}  


class Subject { 
    private List<Observer> observers=new ArrayList<Observer>(); 
    public void attachObserver(Observer observer) { 
    this.observers.add(observer); 
    } 
    public void detachObserver(Observer observer) { 
     this.observers.remove(observer); 
    } 
    public void notifyObservers() { 
    for (Observer observer: this.observers) 
     observer.update(this); 
    } 
} 

class PairOfNumbers extends Subject { 
    private double number1, number2; 
    public double getNumber1() { return this.number1; } 
    public double getNumber2() { return this.number2; } 
    public void setNumbers(double d1, double d2) { 
    this.number1=d1; this.number2=d2; 
    this.notifyObservers(); // don't forget to do this! 
    } 
} 

abstract class Observer { 
    public Observer(Subject subject) { 
    subject.attachObserver(this); 
} 

abstract public void update(Subject subject); 
} 

class SumObserver extends Observer { 
    public SumObserver(PairOfNumbers pair) { 
    super(pair); 
    } 
    public void update(Subject subject) { 
    PairOfNumbers numbers=(PairOfNumbers)subject; 
    System.out.println("New sum is: "+(numbers.getNumber1()+numbers.getNumber2())); 
    } 
} 

class ProductObserver extends Observer { 
    public ProductObserver(PairOfNumbers pair) { 
     super(pair);   
    } 
    public void update(Subject subject) { 
    PairOfNumbers numbers=(PairOfNumbers)subject; 
    System.out.println("New product is: "+(numbers.getNumber1()*numbers.getNumber2())); 
    } 
} 

好吧,現在我想創建另一個繼承自上述類的類。

class MultiSubjectObserver extends Observer{ 
    public MultiSubjectObserver(PairOfNumbers pair){ 
     super(pair); 
    } 

    public void addSubject(PairOfNumbers pair){ 
     pair.attachObserver(this); 
    } 

    public void update(Subject subject){ 
     PairOfNumbers numbers=(PairOfNumbers)subject; 
     System.out.println("MultiSubjectObserver activated with numbers: " + (numbers.getNumber1())+", "+(numbers.getNumber2())); 
    }   
} 

有沒有辦法在MSO類中創建一個不需要參數/參數的構造函數?例如

public MultiSubjectObserver(){ 
    //enter code here 
} 

請指導我這一個。一直在想幾天。提前致謝! :D

該指令旨在:修改源代碼以處理每個Observer的任意數量的Subject對象。

預期輸出:

New sum is: 30.0 
MultiSubjectObserver activated with numbers: 20.0, 10.0 
New product is: -150.0 
MultiSubjectObserver activated with numbers: -10.0, 15.0 
+1

是的,如果你也給'Observer'一個無參數的構造函數。 – immibis 2014-09-28 01:12:05

+0

@immibis:不是絕對必要的 – 2014-09-28 01:16:17

回答

0

是的,你可以做到這一點,創建一個無參數的子類,但你還是必須調用構造子內的ARG-需要超級構造函數。

此:

class Child extends Super { 
    public Child() { 
     super(args_are_needed); 
    } 
} 

最棘手的部分是 - 怎麼進入這個默認情況下,超級構造函數?你的情況,這可能是:

public MultiSubjectObserver(){ 
    super(null); 
} 

警告:,這將導致當超類的構造函數被調用時,由於線路,subject.attachObserver(this); NullPointerException異常,所以沒有,你不能這樣做。

更好的解決方案:確保MultiSubjectObserver不從觀察者延伸!

也許是這樣的:

class MultiSubjectObserver { 
    private List<Observer> observerList = new ArrayList<Observer>(); 

    public void addSubject(PairOfNumbers numbers1) { 
     observerList.add(new InnerObserver(numbers1)); 
    } 

    private class InnerObserver extends Observer { 
     public InnerObserver(Subject subject) { 
     super(subject); 
     } 

     @Override 
     public void update(Subject subject) { 
     System.out.println("From multi-observer: " + subject); 
     } 
    }  
} 

但對於這個工作,你必須給PairOfNumbers一個體面的toString方法,或許,

@Override 
public String toString() { 
    return String.format("[%.4f, %.4f]", number1, number2); 
} 

編輯
基於輸出:

class MultiSubjectObserver { 
    private static final String FORMAT_STRING = "MultiSubjectObserver activated with numbers: %.1f, %.1f%n"; 
    private List<Observer> observerList = new ArrayList<Observer>(); 

    public void addSubject(PairOfNumbers numbers1) { 
     observerList.add(new InnerObserver(numbers1)); 
    } 

    private class InnerObserver extends Observer { 
     public InnerObserver(Subject subject) { 
     super(subject); 
     } 

     @Override 
     public void update(Subject subject) { 
     System.out.printf(FORMAT_STRING, ((PairOfNumbers)subject).getNumber1(), ((PairOfNumbers)subject).getNumber1()); 
     } 
    } 
} 

儘管這個演員有點不合適。我喜歡toString()版本更多更好。

+0

OMG!非常感謝你!拯救了我的一天! :) – NewbieCoder 2014-09-28 01:16:58

+1

@ user3774597:注意我的答案底部的警告。爲什麼你覺得你需要一個沒有參數的構造函數的子類? – 2014-09-28 01:17:29

+0

Ouwh,這是在我的Main方法中,給定的構造函數是'MultiSubjectObserver m = new MultiSubjectObserver();',我不允許改變它。 – NewbieCoder 2014-09-28 01:19:38