-1

Let's imagine that I have two classes Person1 and Person2, which implements the interface History. I want to have a static method inside History interface that return Person1 or Person2 depending on a string like this :

public static Object getPerson(String p){
    switch(p){
        case "a":
            return new Person1();
        default:
            return new Person2();
    }
}

I don't have any error here. But how to use it in another class, in order to get methods from Person1 or Person2 ? I tried to do this :

Object env = IEnvironment.getPerson(clientEnv);

But I can't write env.myMethod() for example.

Is an interface the right solution ? How to achieve this ? Thanks!

faceID
  • 81
  • 7
  • 5
    that method will never compile, since it expects a String as returntype, and you return either a Person1, or a Person2 – Stultuske Oct 30 '19 at 13:04
  • Yeah, that method on top should definitely not compile due to what the other commenter said. We might need more info on this one, why do you want a single method to be able to return two different types? How is Person1 different from Person2? Please provide a [mre] so we can get a better understanding of what you're trying to do. – yur Oct 30 '19 at 13:07
  • What you're searching for is probably the factory pattern, there was a similar post [here](https://stackoverflow.com/questions/58570377/how-to-avoid-cascading-if-case-statements-in-a-factory-class) and a list (here)[https://stackoverflow.com/questions/1673841/examples-of-gof-design-patterns-in-javas-core-libraries/2707195#2707195]. – Curiosa Globunznik Oct 30 '19 at 13:07
  • You're probably looking to implement some version of the [factory](https://www.tutorialspoint.com/design_pattern/factory_pattern.htm) design pattern, where different classes implementing the same interface can be provided to the caller, given relevant parametrization. Note that from the OO perspective, it's hard to imagine how a `Person` could implement `History`, and definitely a method returning `String` cannot return a different object. – Mena Oct 30 '19 at 13:08
  • I appreciate that you tried to reduce your code to a minimal example, it is not well done. For your first snippet you said *"I don't have any error here."* which is impossible, then you wrote you tried `IEnvironment.getEnvironment(clientEnv)` which is strange, since your method is `getPerson` not `getEnvironment` and then you wrote you can't use `env.myMethod()` which is yet another different method name. So when you create a minimal example, please be consistent. Your question is currently just confusing. – Tom Oct 30 '19 at 13:17

2 Answers2

1

You can create a Interface and let these classes implements this interface. Then from switch you can return this interface.

 public static History getPerson(String p){
    switch(p){
        case "a":
            return new Person1();
        default:
            return new Person2();
    }
 }
Rahul Agrawal
  • 623
  • 1
  • 5
  • 18
  • OP already said both classes implement the interface `History`, so why do you suggest to create another one? – Tom Oct 30 '19 at 13:09
  • OP original posting didn't mention they were already implementing an interface. – locus2k Oct 30 '19 at 13:24
  • @locus2k So you say OP added the sentence *"which implements the interface History."* after first posting the question? – Tom Oct 30 '19 at 13:25
  • Looking at the history apparently I am mistaken as it was there. Could've sworn it wasn't otherwise my answer (now deleted) would've been different – locus2k Oct 30 '19 at 13:27
  • @locus2k Don't get tricked by the history, it is possible that OP added it. There is a grace period where someone can edit their own post before an history entry is created. That period last for 5 minutes or until someone writes a comment or an answer. So you can be correct when you saw the question before Stultuske wrote the first comment (which would cancel the grace period). I haven't seen this question that early, so I can't tell if OP added something or not, that's why I was asking you. – Tom Oct 30 '19 at 13:34
0

Do you want something like this:

$ java Foo a
Person1
$ java Foo b
Person2
$ cat Foo.java
/**
 * This is just a container so I can do it all in one class.
 */
public class Foo {
    // Static just for packaging purposes
    public static class History {
        public void printMe() { System.out.println("History"); }
    }

    // Static just for packaging purposes
    public static class Person1 extends History {
        public void printMe() { System.out.println("Person1"); }
    }

    // Static just for packaging purposes
    public static class Person2 extends History {
        public void printMe() { System.out.println("Person2"); }
    }

    public static History makePerson(String str) {
        History retVal = (str.equals("a")) ? new Person1() : new Person2();
        return retVal;
    }

    public static void main(String[] args) {
        History person = makePerson(args[0]);
        person.printMe();
    }
}

(Edited to test it and to properly use .equals intead of == in the comparison.)

Joseph Larson
  • 8,530
  • 1
  • 19
  • 36