Java语法:谁可以将接口作为对象?

时间:2012-12-27 15:09:53

标签: java syntax interface observer-pattern

我正在研究Observer模式,我遇到了一些困惑。

当我读到这行代码时:

IObserverSubscribe user1= new ConcreteObserverYoutubeUser();

我认为界面IObserverSubscribe user1正在创建并实例化new ConcreteObserverYoutubeUser()。这对我来说有点混乱,因为通常被声明的同一个类也在实例化。应该是这样的:

IObserverSubscribe user1= new IObserverSubscribe();

为什么界面修饰能够实例化另一个类?

以下完整代码:

主:

package observerpattern;

public class ObserverPattern {

    /**
     * The observer pattern is a software design pattern in which
     *  an object, called the subject, maintains a list of its dependents,
     *  called observers, and notifies them automatically of any 
     *  state changes, usually by calling one of their methods.
     *  It is mainly used to implement distributed event handling systems.
     *  The Observer pattern is also a key part in the familiar
     *  Model View Controller (MVC) architectural pattern. 
     */
    public static void main(String[] args) {

        SubjectYouTubeChannel sytc= new SubjectYouTubeChannel();// create youtube channel
        IObserverSubscribe user1= new ConcreteObserverYoutubeUser();
        IObserverSubscribe user2= new ConcreteObserverYoutubeUser();
        IObserverSubscribe moderator1= new ConcreteObserverYoutubeModerator();

        sytc.Subscribe(user1);
        sytc.Subscribe(user2);
        sytc.Subscribe(moderator1);
        sytc.Unsubscribe(user2);

        sytc.notifySubscribers();


    }

}

主题:

package observerpattern;

import java.util.ArrayList;
import java.util.List;
import observerpattern.IObserverSubscribe;

public class SubjectYouTubeChannel {    
    private List<IObserverSubscribe> subscribers = new ArrayList<IObserverSubscribe>(); 
    public void Subscribe(IObserverSubscribe ios){
        subscribers.add(ios);       
    }   
    public void Unsubscribe(IObserverSubscribe ios){        
        subscribers.remove(ios);
    }   
    public void notifySubscribers(){        
        for(IObserverSubscribe ios : subscribers ){         
            ios.Notify();           
        }       
    }
}

界面观察员:

package observerpattern;

public interface IObserverSubscribe {

    void Notify();

}

具体观察员:

package observerpattern;

public class ConcreteObserverYoutubeUser implements IObserverSubscribe{

    @Override
    public void Notify() {
        System.out.println("User watches video, comments, ect");

    }

}

3 个答案:

答案 0 :(得分:2)

new IObserverSubscribe();

这是非法,因为无法实例化接口 - 根据定义,它们没有任何...定义其方法。

IObserverSubscribe user1= new ConcreteObserverYoutubeUser();

左侧显示user1类型为至少 IObserverSubscribe,即指向实例,其类型实现接口。< / p>

右侧实际上会创建具体类型的实例并分配给user1。这是可能的,因为具体类型实现了接口

答案 1 :(得分:1)

  

IObserverSubscribe user1 = new ConcreteObserverYoutubeUser();我认为   接口IObserverSubscribe user1正在创建和实例化   新的ConcreteObserverYoutubeUser()。这对我来说有点混乱   因为通常同一个被宣布的类也是   实例化。应该是这样的:

     

IObserverSubscribe user1 = new IObserverSubscribe();

不,你不能实例化接口。

IObserverSubscribe user1= new ConcreteObserverYoutubeUser();

这将创建ConcreteObserverYoutubeUser的实例,它是IObserverSubscribe的子类(或实现类)。

答案 2 :(得分:1)

考虑界面的作用以及观察者模式的用途。

ConcreteObserverYoutubeUser实现IObserverSubscribe接口,因为它需要保证它具有“Notify()”方法。因此,所有应该是“IObserverSubscribers”的类在收到通知时都需要做一些事情。

如果你能做到以下几点,那就会破坏观察者模式的目的:

 IObserverSubscribe user1= new IObserverSubscribe();

youtube主持人和youtube用户具有不同的功能,因此您不能对两者使用相同的Notify方法(请参阅下面的修改后的代码):

用户类:

 package observerpattern;

 public class ConcreteObserverYoutubeUser implements IObserverSubscribe{ 

     @Override
     public void Notify() {
         sendEmail("A new video was added! It might be a cat video, so you should " +
       "probably view it, vote on it, comment on it, or ignore it.");

     }
     @Override
     public void watchVideo(Video v) {
       //...
     }
     @Override
     public void giggleAtCatVideo() {
         //..
     }


 }

主持人类:

 package observerpattern;

 public class ConcreteObserverYoutubeModerator implements IObserverSubscribe{    
     @Override
     public void Notify() {
         sendEmail("New video added, see if it should be deleted or if there is copyright infringement.");
     } 
     @Override
     public void deleteVideo(Video v) {
         //..
     }
 }

为什么这有用?好吧,因为你可以创建另一个类(在这种情况下,SubjectYouTubeChannel),它可以容纳实现“IObserverSubscribe”接口的对象。当关于该主题的某些内容发生变化时,您可以通知每个观察者与该主题相关联的内容,以便所有观察者都知道某些内容已发生变化。

一个更好的例子是如果SubjectYouTubeChannel有一个“addVideo”方法(见下文),并在减速剂类和用户类的通知方法发送的不同的电子邮件到他们提醒他们的变化。

package observerpattern;

import java.util.ArrayList;
import java.util.List;
import observerpattern.IObserverSubscribe;

public class SubjectYouTubeChannel {    
    private List<IObserverSubscribe> subscribers = new ArrayList<IObserverSubscribe>(); 
    public void Subscribe(IObserverSubscribe ios){
        subscribers.add(ios);       
    }   
    public void Unsubscribe(IObserverSubscribe ios){        
        subscribers.remove(ios);
    }   
    public void notifySubscribers(){        
        for(IObserverSubscribe ios : subscribers ){         
            ios.Notify();           
        }       
     }
 public void addVideo(Video v){
     //... video add code
        notifySubscribers();
 }
 }

这意味着你可以做这样的酷事:

 package observerpattern;

 public class ObserverPattern {

    /**
     * The observer pattern is a software design pattern in which
     *  an object, called the subject, maintains a list of its dependents,
     *  called observers, and notifies them automatically of any 
     *  state changes, usually by calling one of their methods.
     *  It is mainly used to implement distributed event handling systems.
     *  The Observer pattern is also a key part in the familiar
     *  Model View Controller (MVC) architectural pattern. 
     */
    public static void main(String[] args) {

        SubjectYouTubeChannel sytc= new SubjectYouTubeChannel();// create youtube channel
        IObserverSubscribe user1= new ConcreteObserverYoutubeUser();
        IObserverSubscribe user2= new ConcreteObserverYoutubeUser();
        IObserverSubscribe moderator1= new ConcreteObserverYoutubeModerator();
        Video v = new Video() //imagine that class exists

        sytc.Subscribe(user1);
        sytc.Subscribe(user2);
        sytc.Subscribe(moderator1);
        sytc.Unsubscribe(user2);

        sytc.addVideo(v);
    //notifySubscribers() is called within SubjectYouTubeChannel's addVideo() so
    //all users and moderators who subscribe to the channel have been notified with 
    //messages corresponding to what they should do

    }
 }