Search code examples
javasyntaxinterfaceobserver-pattern

Java Syntax: Who can an interface be an object?


I'm currently studying the Observer pattern and I've come across some confusion.

When I read this line of code:

IObserverSubscribe user1= new ConcreteObserverYoutubeUser();

I think the interface IObserverSubscribe user1 is creating and instantiating new ConcreteObserverYoutubeUser(). That is a little confusing to me because usually the same class that is being declared is also instantiating. Should it be like this:

IObserverSubscribe user1= new IObserverSubscribe();

Why is the interface decoration able to instantiate a another class?

Full code below:

Main:

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();


    }

}

subject:

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();           
        }       
    }
}

Interface Observer:

package observerpattern;

public interface IObserverSubscribe {

    void Notify();

}

Concrete Observer:

package observerpattern;

public class ConcreteObserverYoutubeUser implements IObserverSubscribe{

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

    }

}

Solution

  • new IObserverSubscribe();
    

    This is illegal because you cannot instantiate an interface - they by definition do not have any ... definitions of their methods.

    IObserverSubscribe user1= new ConcreteObserverYoutubeUser();
    

    The left side here says that user1 is of type atleast IObserverSubscribe, i.e points to an instance whose type implements the interface.

    The right side on the other hand actually creates an instance of a concrete type and assigns to user1. This is possible because the concrete type implements the interface.