it-roy-ru.com

расширяет класс с помощью частного конструктора

Предположим, у нас есть следующий код:

class Test {
    private Test() {
        System.out.println("test");
    }

}

public class One extends Test {

    One() {
        System.out.println("One");
    }

    public static void main(String args[]) {

        new One();
    }
}

Когда мы создаем объект One, он изначально назывался конструктором родительского класса Test(). но так как Test() был закрытым - мы получаем ошибку . Сколько стоит хороший пример и выход из этой ситуации?

43
user471011

Выхода нет. Вы должны создать доступный (protected, public или по умолчанию) супер-конструктор, чтобы иметь возможность расширять test.

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

Если у вас есть class только с конструкторами private, вы также можете изменить class на final, поскольку он вообще не может быть расширен.


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

class Test {
    private Test() {
        System.out.println("test");
    }
    public static Test getInstance(){
        return new Test();
    }
    public void methodA(){
        //Some kind of implementation
    }
}

public class One {
    private final Test test;
    One() {
        System.out.println("One");
        test = Test.getInstance();
    }

    public void methodA(){
        test.methodA();
    }

    public static void main(String args[]) {
        new One();
    }
}
43
Colin Hebert

Сделайте конструктор test не -private или переместите One в test.

Кстати, ваш пример кода содержит несколько проблем:

  • классы должны иметь название case (Test вместо test)
  • Я бы предложил сделать конструктор Oneprivate, если он не вызван из другого класса в том же пакете
1
Mot

На самом деле я обнаружил, что есть выход. Как это:

class Base {
    private Base() {

    }

    public void fn() {
        System.out.println("Base");
    }

    public static class Child extends Base {
        public void fn() {
            System.out.println("Child");
        }
    }

    public static Base getChild() {
        return new Child();
    }
}

Теперь вы можете использовать getChild (), чтобы получить экземпляр расширенного класса.

0
delphifirst