2014-09-28 142 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