Java子类有一种方法可以返回其类

3

好的,也许这是一个愚蠢的问题。但我想知道是否可以用Java完成这个任务。

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

在子类中

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

我的问题是,我能在子方法中返回类类型吗?我的意思是,在ParentClass中添加一些代码,这样我就可以像下面这样做吗?
例如:
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() { }
}

其他例子

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

再举一个例子

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

如果您看到Sub1Class、Sub2Class和Sub3Class中的getItClassObject方法,它们将遵循其类。但我不想为每个子类添加相同的方法,只想在ParentClasss中添加一些代码(如果可行),这样在子类中,我只需直接调用getItClassObject而无需在每个子类中编写所有代码。
通常我会像这样在ParentClass中添加方法。
abstract public class ParentClass<T> {
  abstract public T getTest();
  public Object getItClassObject() { }
}

所以在子类中,我只需实例化该类,但我仍然需要再次转换 :(

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

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

我认为这在Java中无法完成。但我不知道是否有解决此问题的线索。谢谢。


你如何在ParentClass中实现getItClassObject方法?这个方法也应该是抽象的吗? - Mike Deck
是的,那只是一个例子。我的意思是该方法将被添加到ParentClass中,因此它不会是一个抽象类。每个子类都不需要覆盖,因为已在ParentClass中声明。但是所声明的方法必须返回其类类型。 - Jef
4个回答

3

我想这是您想要的。以下是编译结果:

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

正如您所见,A声明getA()方法返回A。但是,您可以在子类中限制返回类型,如下所示。


1
我知道...但是我必须为我创建的每个子类再次覆盖。我必须为B类重写getA返回类B,并且我必须为C类重写getA返回类C。目前在A类中,我有公共方法Object getA(),它的子类不需要覆盖。但是在调用子类方法时,我必须再次进行类型转换(因为返回Object)。 - Jef
是的...你的解决方案是两种可能的解决方案之一(而不是我期望的第三种解决方案)。我更喜欢使用强制转换而不是你的方法,因为我不需要覆盖所有子类。谢谢。 - Jef

1
我能想到的唯一方法是在扩展父类时告诉它子类是什么(就像你用“T”一样)。例如:
public abstract class ParentClass<T,U> { 
    abstract public T getTest();
    abstract public U getItClassObject();
}

然后你可以这样定义你的子类:

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

那么您可以随心所欲地操作,无需进行类型转换:

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

嗨,Craigo,我不想添加U参数(而T已经存在)的问题是我的所有服务类都已经继承了只有T的ParentClass。我同意你的例子,但我之前就考虑过这个问题,那不是我想要的。 - Jef

1

我不确定我是否正确理解了您的意图,但我认为内置的Object.getClass()方法将实现您想要的功能。给定定义为:

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()会返回正确的运行时类

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

我想要在SubClassString类中的getTest方法返回值为SubClassString类,而在SubClassInteger类中的返回值为SubClassInteger类,而不需要显式地输入它们的类名。如果可能的话,只需在抽象类中编写一次该方法即可。我认为这在Java中是无法实现的 :( - Jef

0
如果您的对象具有无参构造函数(或者所有对象都具有某种一致的构造函数形式),则可以使用反射来实现。以下是一些伪代码:
public class MyClass {

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

}

这是使用类的运行时类型,因此子类将返回其类型。但是,这仅适用于无参构造函数。


如果你有构造函数,也可以这样做。只需键入:Class clazz = Class.forName("xxx"); Constructor constructor = clazz.getConstructor(String.class); return constructor.newInstance("我可以实例化带参数的构造函数"); 这不是我想要的。 - Jef

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接