0

Let's say, I have two classes that look like this:

public class classA {
    private Boolean is_started;

    public classA(Boolean is_started) {
        this.is_started = started;
    }
    public Boolean getIs_started(){
        return this.is_started;
    }
}

public class classB {
    private String token;

    public classA(String token) {
        this.token = token;
    }
    public String get_token(){
        return this.token;
    }
}

I am calling those two classes from another class like this:

public class CallingClass {

    public void function1() {
        ClassA stepA = new ClassA(<some boolean>);
        commonFunction(stepA);
}
    public void function2() {
        ClassB stepB = new ClassB(<some string>);
        commonFunction(stepB);
}
    public <T> void commonFunction(Class<T> dataObject) {
        //An if statement that has a condition that only calls a function in classB {
            String token = dataObject.get_token();
        }
        //An if statement that has a condition that only calls a function in classA {
        Boolean is_started = dataObject.getIS_started();
        }
//It returns error : The method [get_token()/getIS_started()] is undefined for the type Class<T>

I want to make sure that I can call different objects without specifying them in the function. For example, I want to supply ClassA and ClassB as an argument to the commonFunction as in the example above. How do I make it happen with generics?

4
  • trying to understand your question a little better, so in your generic function commonFunction, you want to invoke a method get_token that is in both classA and classB and return whatever is the result of that? Commented Nov 22, 2021 at 1:42
  • Your "classA" doesn't have a method get_token. Class<T> refers to java.lang.Class. You call your class classA with a lowercase in one snippet and ClassA with uppercase in the next. Neither class A or B extend/implement Class<T>. Not really clear what you're asking or trying to achieve. Commented Nov 22, 2021 at 1:43
  • You need some way to tie the two classes together, such as an interface (as Class doesn't define a getToken method) Commented Nov 22, 2021 at 1:44
  • I added a few statements for clarification. @scigs Commented Nov 22, 2021 at 1:51

3 Answers 3

4

You need some way to tie the classes together which says "this instance implements a method called getToken which returns some kind of result"

The simplest place to start would be a interface, for example...

public interface Tokenable<T> {
    public T getToken();
}

Then both ClassA and ClassB would need to implement this interface as required, for example...

public class ClassA implements Tokenable<Boolean> {

    private Boolean started;

    public ClassA(Boolean started) {
        this.started = started;
    }

    @Override
    public Boolean getToken() {
        return started;
    }

}

public class ClassB implements Tokenable<String> {

    private String token;

    public ClassB(String token) {
        this.token = token;
    }

    @Override
    public String getToken() {
        return token;
    }

}

And then you can communalise the call back...

public class CallingClass {

    public void function1() {
        ClassA stepA = new ClassA(false);
        commonFunction(stepA);
    }

    public void function2() {
        ClassB stepB = new ClassB("hello");
        commonFunction(stepB);
    }

    public <T> void commonFunction(Tokenable<T> dataObject) {
        T token = dataObject.getToken();
    }

}

Without providing some kind of common ancestor, you're not really going to be able to get it to work - Class doesn't define a getToken method, so you need some kind of common ancestor in order to call it (there is a "hacky" way to do it, but you really, really, really don't want to go down that rabbit hole)

Sign up to request clarification or add additional context in comments.

2 Comments

Will it work if we were calling different methods of different classes inside the commonFunction? Say, I was calling get_token() and getIs_started() at different times like I have edited in the question above.
@JJ123 Again, you need to define some level of commonality - you can't call a method on a class which doesn't define the functionality (via inheritance or implementation) - this is all part of polymorphism
1

The direct answer to your literal question would be that the only supertype of classA and classB is Object, so your parameter type must be Object, and you can use instanceof to test if it's an instance of a particular type, and if so, cast to that type to do stuff that can only be done with that type:

public void commonFunction(Object dataObject) {
    if (dataObject instanceof classB) {
        String token = ((classB)dataObject).get_token();
    }
    if (dataObject instanceof classA) {
        Boolean is_started = ((classA)dataObject).getIS_started();
    }
}

However, using instanceof like this is evidence of bad design. If the logic for the two different types is separate, then why put them in the same function? If the "token" and "is_started" are supposed to represent the same kind of information, then refactoring them to the same method provided in an interface, like other answers suggested, makes more sense.

Comments

0

It could be that there's something I'm missing about your question because it's not entirely clear what you are trying to achieve but something doesn't seem quite right about the way you're trying to do this.

You have logic in commonFunction that behaves one way if the argument is one type and another way if the argument is the other type. It seems like what you really should do is have that logic inside ClassA and ClassB. So they should both implement some method that behaves one way inside ClassA and the other way inside ClassB. Then commonFunction can treat all arguments the same.

In general, if you are testing the type of an argument and triggering different behaviour in different cases then it's a pretty good indication that the behaviour really belongs inside those classes themselves, provided you are the one defining the classes which you are in this case.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.