Java - Могут ли потомки абстрактного класса ("extends" -ers) создавать себя с помощью абстрактного метода своих родителей? ", Т.е. m = new this ();"? - PullRequest
1 голос
/ 29 августа 2011

Перво-наперво, пожалуйста, имейте в виду, что я пытаюсь выразить свой вопрос как можно лучше, используя мои текущие знания и словарный запас, поэтому, пожалуйста, извините это ...

У меня есть абстрактный класс, в котором я хочу создать метод, в котором он создает себя ... Конечно, это невозможно в абстрактном классе, однако, что я действительно хочу, так это для конкретных детей (тех классов, расширяет "), чтобы унаследовать этот экземпляр, чтобы они могли создать экземпляр себя ...

В основном я хочу сделать следующее:

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

}

* Дополнительная информация **

Спасибо за ответы, но я думаю, что пропустил что-то жизненно важное ...

По сути, я хотел передать self объекта ("this") в некоторые методы некоторых других классов. Однако создание экземпляра другого объекта внутри объекта немного отсталый, я могу просто передать «this», верно ...

Ответы [ 5 ]

2 голосов
/ 29 августа 2011

Вы можете сделать это, используя отражение, что-то вроде:

Abstract a = getClass().newInstance();

Это потому, что getClass () всегда возвращает конкретный класс, поэтому this.getClass () вернет реальный подкласс, а не текущий класс.

Однако помните, что если подкласс определяет пользовательский конструктор, имеющий больше или меньше параметров, чем ваш абстрактный класс, он может потерпеть неудачу. Если вы не укажете в документации, что у подклассов должен быть конструктор с такими заданными параметрами ... но он все равно хрупок.

Вы можете проверить это, используя getClass (). GetConstructors () и посмотреть, какие есть конструкторы, и если есть тот, который вы ожидаете, или даже найти жизнеспособный, в противном случае вы можете поймать исключение, выданное newInstance (..), и оберните это в более описательное исключение для пользователей, чтобы они лучше понимали, что они пропустили ... но это все равно было бы своего рода хаком, потому что нет явной языковой поддержки для такой ситуации .

Другим подходом может быть реализация Cloneable в вашем абстрактном классе, а затем использование метода clone, но это может быть излишним или даже неправильным, если вам нужен новый, чистый экземпляр.

0 голосов
/ 29 августа 2011

Не могли бы вы просто иметь это?

public abstract class AbstractClassWithConstructor {


    public AbstractClassWithConstructor() {
        init();
    }

    protected abstract void init();
}

FYI

В target-c вам необходимо установить это, вызвав метод init.Метод init () будет выглядеть так:

protected AbstractClassWithConstructor init() {
        return this;
    }
0 голосов
/ 29 августа 2011

Вы пытаетесь определить конструктор, который могут использовать подклассы Abstract? Если это так, вы можете просто сделать это так же, как и любой другой конструктор.

public class Abstract {

Abstract() {
    //set fields, etc. whatever you need to do
}

}

public class ConcreteChild extends Abstract{

    ConcreteChild() {
        //call superclass's constructor
        super();
    }
}
0 голосов
/ 29 августа 2011

Что вам на самом деле нужно сделать, это отделить неизменяемые внутренние функциональные возможности от самого абстрактного класса.Так что я мог бы, например, иметь внутренний класс, который действительно инкапсулирует неизменяющуюся функциональность, например:

public class Abstract {

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

   class NonChangingOperations
   {
       public void operationA() {}
   }

}

Фактически вам не нужно сохранять класс NonChangingOperations в качестве внутреннего класса,Вы можете сделать это как внешний служебный класс со своей собственной иерархией классов.

0 голосов
/ 29 августа 2011

Вы не можете сделать это, используя метод экземпляра. Потому что, как следует из названия, методы экземпляра требуют, чтобы экземпляр уже был создан.

...