-2

I have an Interface IGeneralEvents and I have implemented three classes based on it Social, Sport and Traditional. All three of them are using singletons to make sure they are only instantiated once.

The three classes have some additional methods in them which are unique for each one.

I have also created a class to manage these events named EventManager. Depending on the date and time one of these three events will occur through the EventManager. The EventManager will instantiate one of them like below:

public class EventManager {
    
    public EventManager() {
        if (time_is_right()) {
            Social social_event = Social.getInstance();
        }
    }
}

In another class I need to know which is the current running event. So my approach of a solution was to do the following:

public class EventManager {
    public static IGeneralEvents current_event_instance = null;
    
    public EventManager() {
        if (time_is_right()) {
            Social social_event = new Social.getInstance();
            current_event_instance = social_event;
        }
    }
}

I created a static variable in the EventManager of type IGeneralEvents and tried to pass the instance of the event when it was decided in the constructor. When I do that and I call the current_event_instance with a method that does not exist in IGeneralEvents (e.g current_event_instance.chat()) then I obviously get java: cannot find symbol as the method is not available in the Interface.

What is the proper way to follow in order to be able to call something like current_event_instance.chat() from other classes ?

kampias
  • 459
  • 1
  • 10
  • 21
  • Please add a complete example to your question which illustrates the problem, including whatever compiler error messages you get. – tgdavies May 15 '22 at 23:37
  • 3
    It's hard for me to really tell what's going on, but it sounds like you may be working with the wrong abstractions. Users of an interface [should not care what class implements that interface](https://stackoverflow.com/questions/56860). If a method exists in one class but not another, then it _usually_ shouldn't be part of the interface (there are exceptions). – yshavit May 15 '22 at 23:39
  • 3
    I'm with @yshavit, and your question smells of possibly being an [XY Problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) type question. Why do you need to know the type of the reference made to the interface variable? I have to wonder if there is a better overall approach to this problem. Consider using real-world types and code. – Hovercraft Full Of Eels May 15 '22 at 23:40
  • 1
    Whatever your desired behaviour is when you try to call a method from the wrong class - you could write it as a `default` method in the interface. It's not clear whether that meets your requirement or not. Your requirement sounds a little unusual to me. – Dawood ibn Kareem May 15 '22 at 23:51
  • @yshavit I have updated the content to reflect my problem in more detail. – kampias May 16 '22 at 00:06
  • @HovercraftFullOfEels thank you for this XY Problem, was not aware of it and yes i fell into it. I have updated the content of the question which hopefully now reflects my problem with more precision – kampias May 16 '22 at 00:07

1 Answers1

2

There's instanceof which checks if any given reference is an instance of the stated class, and there's the cast operator which does many completely unrelated things - one of them is to treat a given object as some more specific type - if it is of that type, then you can treat it as that type. If it is not, you get a ClassCastException. Combining them:

if (currentInstance instanceof A) {
  A a = (A) currentInstance;
  a.methodThatIsOnlyInA();
}

There's also the .getClass() method that all classes have; but note that if there's also, say, class AChild extends A{}, then:

Iab a = new AChild();
System.out.println(a instanceof A); // Prints true
System.out.println(a.getClass() == A.class); // Prints false
System.out.println(a instanceof AChild); // Prints true
System.out.println(a.getClass() == AChild.class); // Prints true
rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
  • Indeed using the `instanceof` could be a solution but that would mean every time I need to check in different classes about the current instance I would need to do that check. And since there are three different types of classes I would need three different checks every time. – kampias May 16 '22 at 00:15
  • Yes, of course. If your method requires calling the `thisIsOnlyInA()` method, then it should accept an `A`, not an Iab. – rzwitserloot May 16 '22 at 02:59