Question

Tout d’abord, je ne connais pratiquement rien à la théorie des langues et je ne connais presque pas d’autres langues que Java, mais j’avais l’idée que ce serait cool, mais j’ai besoin que vous me disiez:
a: pourquoi ça craint
b: comment la langue x en a-t-elle pendant des années
c: comment mon esprit craint
d: tout ce qui précède

L’idée donnerait à la composition la même facilité de réutilisation du code que le fait extend .

Donc si vous aviez un cours comme celui-ci:

public interface A {  
    public void methodInA();  
}

Et puis vous avez eu un cours comme celui-ci:

public class B {  
    private composed A;
    public B() {
        // construct A within constructor
    }
}

Vous pourrez alors faire ceci:

B myB = new B();
myB.methodInA();

Sans avoir à ajouter la délégation dans la classe de B. Mais vous pouvez également faire la même chose qu'avec l'héritage, c'est-à-dire:

@Overrides
public void methodInA(){
    // B's own delegation method
}

Les inconvénients incluent:

    Les méthodes
  • sont cachées dans le code source, ce qui rend moins évident l'origine de l'appel, mais c'est également le cas avec extend
  • si les champs composés partagent la même signature de méthode, un conflit doit être résolu (comment les interfaces en conflit résolvent-elles ce problème?)
  • si vous vouliez avoir plusieurs champs composés du même type, il y aurait un conflit évident pour quel champ déléguer
  • probablement 100 autres choses que je n'ai pas pensé

Comme je le dis, je ne suis évidemment pas un théoricien du langage, et je n’ai pas passé autant de temps à y penser, l’idée m’a simplement surgi dans la tête et je voulais savoir à quel point je me trompais. Je pense juste que ce serait plutôt cool.

Était-ce utile?

La solution

Je pense que si vous le limitiez de sorte qu'une classe ne puisse utiliser cette fonctionnalité que pour composer une seule classe, cela serait plutôt utile et éviterait de nombreux maux de tête dont il est question.

Personnellement, je déteste l'héritage de classes concrètes. Je suis un fervent partisan du point 14 de Effective Java de Bloch, Je pense que quelque chose comme cela rendrait un peu plus facile la mise en oeuvre de l'idiome qu'il recommande dans cet article.

Honnêtement, si vous saviez vraiment ce que vous faisiez, je parie que vous pourriez écrire une annotation du compilateur qui gèrerait cela. Donc, si vous aviez une barre de classe qui implémentait l'interface IBar, votre classe ressemblerait à ceci:

public class Foo {

  @Delegate(IBar.class)
  private Bar bar;

  // initialize bar via constructor or setter
}

Ensuite, lors de la compilation, Foo pourrait implémenter IBar et toutes les méthodes de cette interface qui n'étaient pas déjà implémentées par Foo finiraient par être générées pour ressembler à ceci:

public Baz method1(Qux val) {
  return bar.method1(val);
}

Comme mentionné ci-dessus, vous souhaiterez limiter le fait qu'un seul champ par classe puisse utiliser cette annotation. Si plusieurs champs avaient cette annotation, vous voudriez probablement générer une erreur de compilation. Sinon, vous pouvez trouver un moyen de coder une sorte de modèle de priorité dans les paramètres qui lui sont transmis.

Maintenant que j'ai écrit ceci, cela semble plutôt cool. Peut-être que je vais jouer avec ça la semaine prochaine. Je mettrai cela à jour si je parviens à comprendre quoi que ce soit.

Autres conseils

Ça a l'air cool mais je pense que cela donne des constructions de langage horribles. Évidemment, il y a un problème si vous déclarez plus d'une "composition" de la même classe, mais même si vous l'interdisez, qu'en est-il du cas où un appel correspond à une méthode dans plus d'une classe composée (différente)? Vous devrez spécifier lequel a été appelé dans la classe principale et vous aurez besoin d'une syntaxe supplémentaire pour cela. La situation devient encore pire s'il y a des membres du public dans les classes.

La composition est utilisée pour éviter les problèmes d’héritage multiple. Permettre une composition comme celle-ci permet effectivement un héritage multiple, du moins en termes de résolution de la méthode à appeler. Étant donné qu'une décision clé en matière de conception avec Java consistait à interdire l'héritage multiple (pour de bonnes raisons), je pense qu'il est peu probable que cela soit introduit en Java.

Je ne suis cependant pas sûr de voir un avantage clair à le faire. Je comprends ce que vous dites. Au moment d'appeler une méthode sur A, vous devez myB.getAInstance (). MethodInA (), mais vous voulez que myB.methodInA ().

Mais que se passe-t-il si vous avez plusieurs instances de A? Comment l'appel de méthode serait-il résolu? Plusieurs fois, la composition implique une association un à plusieurs, donc B a plusieurs instances de A. Que se passe-t-il ensuite?

Je suis d'accord avec vos inconvénients énumérés. Cela peut simplement causer trop de confusion qu’il ne vaut la peine.

Découvrez ce que l'on appelle "Mixins". dans certaines langues et " Roles " dans le système Perl 5 Moose OO.

Il faut également prendre en compte la différence entre composition et agrégation . Comment le compilateur sait-il si vous voulez dire des relations "est-a" ou "a-a"?

  • Le graphe d'objet entier devient-il éligible pour la récupération de place ou uniquement la tête du graphe?

Quelques outils et infrastructures de cartographie ORM autour / autour d’eux fournissent des relations d’appartements ou a-plusieurs entre objets persistants et certains permettent également la suppression en cascade ( pour la composition). Je ne connais pas d’office qui fournisse le sucre syntaxique simple que vous recherchez.

En fait, à bien y penser, les idiomes MetaClass et MetaProgramming de Groovy peuvent fournir quelque chose de très similaire, avec une délégation 'magie automatique'.

L'héritage multiple est autorisé en C ++, je le sais, mais c'est le même processus de pensée. Java a été conçu pour ne pas autoriser l'héritage multiple, ce qui réduirait la confusion, donc les bugs et les exploits.

Ce que vous avez suggéré est en conflit direct avec les principes de Java.

Cela dit, ce serait cool (pas nécessairement utile). Je suis un programmeur Java qui est passé de C ++. J'aime pouvoir faire mes propres erreurs.

scroll top