web-dev-qa-db-fra.com

étend la classe avec constructeur privé

Supposons que nous ayons le code suivant:

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

Lorsque nous créons un objet One, celui-ci s'appelait à l'origine le constructeur de la classe parent Test(). mais comme Test() était privé - nous obtenons une erreur… .. Combien coûte un bon exemple et un moyen de sortir de cette situation?

43
user471011

Il n'y a pas moyen de sortir. Vous devez créer un super constructeur disponible (protected, public ou par défaut) pour pouvoir étendre test.

Ce type de notation est généralement utilisé dans les classes d'utilitaires ou les singletons, où vous ne voulez pas que l'utilisateur crée lui-même une instance de votre classe, soit en l'étendant et en instanciant la sous-classe, soit en appelant simplement un constructeur de votre classe.

Lorsque vous avez une variable class avec uniquement des constructeurs private, vous pouvez également modifier la variable class en final car elle ne peut pas être étendue du tout.


Une autre solution serait d'avoir une méthode dans test qui crée des instances de test et qui délègue chaque appel de méthode de One à une instance test. De cette façon, vous n'avez pas besoin d'étendre 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

Définissez le constructeur de test non -private ou déplacez One dans test.

BTW, votre exemple de code contient quelques problèmes:

  • les classes doivent être nommées title case (Test au lieu de test)
  • Je suggèrerais de faire le constructeur de Oneprivate à moins qu'il soit appelé depuis une classe différente dans le même paquet
1
Mot

En fait, j'ai trouvé qu'il y avait un moyen de sortir. Comme ça:

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

Maintenant, vous pouvez utiliser getChild () pour obtenir une instance de la classe étendue.

0
delphifirst