8
votes

Solution de contournement pour les attributs abstraits en Java

in Scala je voudrais écrire une classe abstraite avec un attribut abstrait Path code>: xxx pré>

Java ne connaît pas les attributs abstraits et je me demande quel serait le meilleur façon de travailler autour de cette limitation. P>

Mes idées: p>

a) strong> Paramètre constructeur p> xxx pré>

b) Strong> Méthode abstraite P>

abstract class Base { // could be an interface too

  abstract String getPath();

}

class Sub extends Base {

    public String getPath() {
        return "/demo/";
    }

}


3 commentaires

AVERTISSEMENT: B) ne compile pas. Vous devez ajouter abstrait modificateur de résumé de la méthode abstraite.


Question connexe: Stackoverflow.com/Questions/2371025/ABRact-variables-in -ja va


FYI: Scala fonctionne sur la JVM, qui ne prend pas en charge les champs abstraits, SCALA utilise donc essentiellement des méthodes abstraites en interne.


6 Réponses :


1
votes

Si le chemin ne change jamais, j'irais une option A, sinon j'irais pour option b.

Un autre aspect est que la valeur du chemin peut ne pas être disponible au moment de la construction. Dans ce cas, l'option A est en quelque sorte exclue. En comparant à votre code SCALAA cependant, il semble que chemin est disponible au moment de la construction.


2 commentaires

Oui, chemin est disponible à l'heure de la compilation. Pourquoi préféreriez-vous l'option b) si le chemin doit être immuable?


Laisser la sous-classe de remplacement getpath semble être une chose raisonnable à faire si le chemin peut être calculé différemment parfois. Une sous-classe future pourrait par exemple vouloir lire le chemin d'un fichier de configuration qui change pendant l'exécution ou quelque chose, puis il n'a pas de sens d'avoir une variable protégée pour cela.



0
votes

Vous pouvez essayer de créer une méthode protégée pour définir la valeur de la variable. Appelable seulement des classes dans le même paquet.


1 commentaires

Mais le compilateur ne ferait pas d'appeler cette méthode dans une sous-classe, de sorte que la valeur puisse être laissée inintitualisée.



0
votes

Je choisirais l'option B car si, pour une raison quelconque, un chemin dépend d'autres attributs, il n'est pas vraiment agréable de définir l'attribut dans la superclasse chaque fois que les autres modifications d'attribut. Si vous devez mettre en œuvre le getter, il n'y a pas de problème. Je ne peux pas penser à un cas particulier où l'option A serait plus utilisable.


0 commentaires

6
votes

Ce que Scala fait en interne ce que vous décrivez en tant que méthode B.

Prenez la classe d'exemple suivante: P>

public abstract class Test extends java.lang.Object implements scala.ScalaObject{
    public abstract java.lang.String path();
    public Test();
}


0 commentaires

1
votes

L'équivalent est B car les valeurs sont fixes.

L'option A reçoit le chemin du constructeur et cette valeur pourrait être calculée pendant l'exécution qui n'est pas ce que la classe Sub dans l'exemple Scala est en route.


0 commentaires

0
votes

est probablement bien - le paramètre Constructor est probable plus simple s'il n'y aura jamais de calcul impliqué (auquel cas vous voudrez peut-être effectuer la finale du champ, qui aura l'avantage supplémentaire de s'assurer qu'il est assuré de tout autre constructeur cela peut être ajouté plus tard); tandis que la méthode abstraite vous donne plus de liberté de changer les choses à l'avenir.

Vous pouvez également combiner les deux et disposer d'un champ privé dans le constructeur et de fournir une implémentation concrète (mais pas finale) de la getter qui l'accède.


0 commentaires