3

Ok, maybe this is a stupid question. But i'm just wondering if this can be done in java.

abstract public class ParentClass<T> { 
  abstract public T getTest();
}

in the subclass

public class SubClass extends ParentClass<MyObject> {
  public MyObject getTest() {
    // I can return the object with class MyObject
    return null;
  }
}

My question is can I return the class type in the child method? I mean, is it can be done by adding some code in the ParentClass, so I can do this below?

For example

public class Sub1Class extends parentClass<Object1> {
  public Object1 getTest() { }
  // I want to have a method that return it's class in the superclass
  public Sub1Class getItClassObject() { }
}

other example

public class Sub2Class extends parentClass<Object2> {
  public Object2 getTest() { }
  // I want to have a method that return it's class in the superclass
  public Sub2Class getItClassObject() { }
}

one example again

public class Sub3Class extends parentClass<Object3> {
  public Object3 getTest() { }
  // I want to have a method that return it's class in the superclass
  public Sub3Class getItClassObject() { }
}

if you see, method getItClassObject in Sub1Class, Sub2Class and Sub3Class will follow it's class. But I don't want to add same method for every subclass, just want to add some code (if feasible) in the ParentClasss, so in the subclass, I just can call getItClassObject directly without write all the code in every subclass.

Usually I add method in ParentClass like this.

abstract public class ParentClass<T> {
  abstract public T getTest();
  public Object getItClassObject() { }
}

so in the subclass I just instance the class, but I have to cast again :(

Sub1Class sub1Class = new Sub1Class();
Sub1Class after1Cast = (Sub1Class) sub1Class.getItClassObject();

Sub2Class sub2Class = new Sub2Class();
Sub2Class after2Cast = (Sub2Class) sub2Class.getItClassObject();

I think it cannot be done in java. But I don't know if there is a clue to solve this. Thanks

2
  • How would you be able to implement getItClassObject in the ParentClass? Should that method be abstract as well? Commented Oct 13, 2010 at 18:05
  • yeah, that's only an example. I mean the method will be added in the ParentClass so it will not be an abstract class. And each subclass do not need to override, because already declared in the ParentClass. But the declared method must return it's class type. Commented Oct 14, 2010 at 16:19

4 Answers 4

3

This is what you want I think. The following compiles:

abstract class A {
    public abstract A getA();
}

class B extends A {
    // Declared to return a B, but it still properly overrides A's method
    @Override
    public B getA() {
        return new B();
    }
}

class C extends A {
    // Declared to return a B, but it still properly overrides A's method
    @Override
    public C getA() {
        return new C();
    }
}

As you can see, A declares that the getA() method returns an A. But, you can restrict the return type in subclasses as shown.

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

2 Comments

i know that... but I have to override again for every subclass that I create. I have to override getA return class B for B class, and I have to override getA return class C for C class. Currently in class A, I have method public Object getA() and it's subclass do not need to override. But every method that called in the subclass class, I have to cast again (because return Object)
yeah... your solution is one of two possible solution (instead of if I have the third solution as I expected). I prefer to use casting rather than your way because I don't need override all of the subclass. Thanks
1

I'm not sure if I understand your intent correctly, but I think the built-in Object.getClass() method will do what you want. Given classes defined as:

public abstract class ParentClass<T> {
  public abstract T getTest();
}

class SubClassString extends ParentClass<String> {
   public String getTest() {
      return "";
   }
}

class SubClassInteger extends ParentClass<Integer> {
   public Integer getTest() {
      return Integer.valueOf(0);
   }
}

getClass() will return the correct run-time class

  public static void main(String[] args) {
      SubClassString subString = new SubClassString();
      // displays "class SubClassString"
      System.out.println(subString.getClass()); 

      SubClassInteger subInteger = new SubClassInteger();
      // displays "class SubClassInteger"
      System.out.println(subInteger.getClass());

      ParentClass<?> parentInstance = new SubClassInteger();
      // displays "class SubClassInteger"
      System.out.println(parentInstance.getClass());  
  }

1 Comment

I want the method in SubClassString the return value (for method getTest) is Class SubClassString, and the return value in SubClassInteger is SubClassInteger without explicitly have to type it's class. If possible just type the method in the abstract class (once only). I think this cannot be done in java :(
1

The only way I can think of is by telling the parent class what the subclass is when you extend it (just like you did with 'T'). Eg:

public abstract class ParentClass<T,U> { 
    abstract public T getTest();
    abstract public U getItClassObject();
}

They you define your subclass like so:

public class Sub1Class extends ParentClass<Object1,Sub1Class> {
    public Object1 getTest() { }
    public Sub1Class getItClassObject() { }
}

Then you can do what you want without the typecast:

Sub1Class sub1Class = new Sub1Class();
Sub1Class after1Cast = sub1Class.getItClassObject();

1 Comment

Hi Craigo, the problem that I do not want to add the U parameter (instead T is already exist) is all of my service class is already inherit the ParentClass with T only. I agree with your example, but I have thought it before, that's not what I want.
0

If your objects have no-arg constructors (or some consistent form of constructor across all of them), you can use reflection to do it. Some pseudocode would be

public class MyClass {

    public MyClass instantiateType() {
       Class<?> actualClass = getClass();
       return actualClass.newInstance();
    }

}

This is using the runtime type of the class, so subclasses will return their type. This works only for a no-arg constructor though.

1 Comment

if you have constructor, you can do that too. just type. Class clazz = Class.forName("xxx"); Constructor constructor = clazz.getConstructor(String.class); return constructor.newInstance("i can instance constructor with arg"); That's not what I want

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.