【问题标题】:Java - Can the children of an abstract class (the "extends"-ers) instantiate themselves via their parents abstract method?" i.e. m = new this();"?Java - 抽象类的子类(“扩展”-ers)能否通过其父类抽象方法实例化自己?”即 m = new this();”?
【发布时间】:2011-08-29 16:12:14
【问题描述】:

首先,请注意,我正在尝试用我目前的知识和词汇尽可能地表达我的问题,所以请原谅...

我有一个抽象类,我想在其中创建一个实例化自身的方法......当然这在抽象类中是不可能的,但是,我真正想要的是具体的孩子(那些“ extends") 来继承这个实例化,这样他们就可以实例化自己....

基本上我想做的是这样的:

MyAbstract a = new this();

但是这是不允许的...有什么方法可以做我想做的事吗?

这是一些非编译的梦想代码(即我希望工作的代码)。基本上我希望 ConcreteChild 调用一个方法,在该方法中它创建自己的对象。该方法是从其父级继承的。

public class Abstract {

    public void instantiateMyConcreteChild()
    {
        Abstract a = new this();
    }

}

public class ConcreteChild extends Abstract{

    public static void main(String[] args) {
        ConcreteChild c = new ConcreteChild();

        c.instantiateMyConcreteChild();
    }

}

* 附加信息 **

感谢您的回复,但我想我错过了一些重要的事情......

基本上,我想将对象的自身(“this”)传递给其他类的一些方法。但是,在一个对象中创建实例化另一个对象有点倒退,我可以只传递“this”,对...

【问题讨论】:

  • 请问,你想达到什么目标?它可能存在更好的方法来做到这一点。
  • 到目前为止,您有四个不同的答案,都试图猜测您真正想要完成什么。你能编辑你的帖子更详细地解释你想要什么吗?
  • 添加了信息,我已经评论了别人的回复。

标签: java this abstract-class concrete


【解决方案1】:

您可以使用反射来做到这一点,例如:

Abstract a = getClass().newInstance();

这是因为 getClass() 总是返回具体类,所以 this.getClass() 将返回真正的子类,而不是当前类。

但是,请注意,如果子类定义了一个自定义构造函数,其参数比抽象类多或少,它可能会失败。除非您在文档中指定子类必须具有具有此类给定参数的构造函数……但无论如何它都很脆弱。

你可以检查它,使用 getClass().getConstructors() 看看有哪些构造函数,如果有你期望的构造函数,甚至搜索一个可行的构造函数,否则你可以捕获 newInstance 抛出的异常(..),并将其包装在对用户更具描述性的异常中,以便他们更好地理解他们错过了什么......但这仍然是一种黑客行为,因为这种情况没有明确的语言支持.

另一种方法是在您的抽象类中实现 Cloneable,然后使用 clone 方法,但如果您想要的是一个新的、干净的实例,这可能是矫枉过正甚至是错误的。

【讨论】:

  • 我不建议使用反射来实例化抽象类,这纯粹是一种 hack
  • 使用建议的代码,您不会实例化抽象类,而是实例化它的实际具体实现。但是,我同意你的观点,这是一个 hack 和脆弱的代码.. 但如果他需要这个用于实验性或非常具体的用例而不是大型代码库,则可以使用脆弱的 hack。
【解决方案2】:

您不能使用实例方法执行此操作。因为顾名思义,实例方法要求实例已经实例化。

【讨论】:

    【解决方案3】:

    您实际上需要做的是将不变的内部功能与抽象类本身分开。所以我可以做的是,例如,有一个真正封装不变功能的内部类,如下所示:

    public class Abstract {
    
       public void instantiateMyConcreteChild()
       {
           Abstract a = new NonChangingOperations();
       }
    
       class NonChangingOperations
       {
           public void operationA() {}
       }
    
    }
    

    事实上,您确实不需要将类 NonChangingOperations 保留为内部类,您可以将其作为具有自己的类层次结构的外部实用程序类。

    【讨论】:

      【解决方案4】:

      您是否尝试定义 Abstract 的子类可以使用的构造函数?如果是这样,您可以像定义任何其他构造函数一样简单地执行此操作。

      public class Abstract {
      
      Abstract() {
          //set fields, etc. whatever you need to do
      }
      
      }
      
      public class ConcreteChild extends Abstract{
      
          ConcreteChild() {
              //call superclass's constructor
              super();
          }
      }
      

      【讨论】:

      • 没有。我正在尝试在抽象类中创建一个可以创建自己类型的对象的方法。
      • 如果我错了,请纠正我。你想创建一个字段,比如说,在其类型被实例化为与它碰巧是的任何具体类相同的类中?
      【解决方案5】:

      你能有这个吗?

      public abstract class AbstractClassWithConstructor {
      
      
          public AbstractClassWithConstructor() {
              init();
          }
      
          protected abstract void init();
      }
      

      仅供参考

      在objective-c中你需要通过调用方法init来设置它。 init() 方法如下所示:

      protected AbstractClassWithConstructor init() {
              return this;
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-16
        • 2015-10-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多