Java8 la méthode par défaut

1 Pourquoi faut-il une méthode par défaut

Avant java 8, le degré de couplage entre l'interface et la classe d' application est trop élevée (étroitement couplée), lorsque l'on souhaite un procédé pour l' addition d' une interface, toutes les classes doivent être suivies pour obtenir la modification. La méthode par défaut pour résoudre ce problème, il peut ajouter de nouvelles méthodes à l'interface, et ne compromettra pas la réalisation de l'interface existante.
Par exemple, l' interface Liste Java8 ajouté méthode de tri. Avant Java8, chaque classe qui implémente l'interface doit être définie pour atteindre la méthode de tri List, sa mise en œuvre ou hériter de la classe parente. Imaginez si l'interface système d' héritage de la liste est très complexe, donc à quel point l' entretien toute la collection du cadre sont!

A cette fin, en Java8 nous avons introduit un nouveau mécanisme: les supports d'interface méthodes indiquées avec la mise en œuvre.

2, un exemple

Dans le Java8 mentionné précédemment ajouté Interface Liste méthode de tri, son code source est la suivante:

Liste public interface étend Collection {

// ...其他成员
    
default void sort(Comparator<? super E> c) {
  ...
  ...
}

}
Vous pouvez le voir, cette nouvelle méthode a le corps de la méthode de tri, modifié par le modificateur par défaut, qui est l'interface de méthode par défaut.

De toute évidence, la méthode par défaut n'est pas statique, il est nécessaire d'invoquer la méthode par défaut par une instance de classe qui implémente l'interface.

Suite à une interface personnalisée à la pratique en utilisant la méthode par défaut.

Interface de taille {public
de méthodes abstraites // commune, un corps de méthode par défaut modifié pas public abstract
int size ();

/*
 * 默认方法,有方法体
 * 任何一个实现了Sized接口的类都会向动继承isEmpty的实现
 */
default boolean isEmpty() {
    return this.size() == 0;
}

}
En fait, avec l'escalade de la version JDK, API continue d'évoluer, la méthode par défaut dans Java8 l'API a été une utilisation intensive de la méthode de tri liste ci - dessus l' interface est l' un d'entre eux.

La différence entre les classes abstraites et
certains étudiants ont trouvé, dans Java8 ajouté méthode d'interface par défaut, ce qui est une classe abstraite devant elle? En fait, il existe des différences entre les deux.

Une classe peut hériter d' une classe abstraite, mais une classe peut implémenter plusieurs interfaces.
Résumé classe a des variables d'instance, et l'interface ne peut avoir des variables de classe

3, la résolution des conflits

Nous savons que le langage Java dans une classe ne peut hériter d'une classe parent, mais une classe peut implémenter plusieurs interfaces. Avec l'introduction de la méthode par défaut dans Java8, il peut y avoir une classe hérite de la même méthode de signature multiple. Dans ce cas, la classe choisira quelle fonction de l'utiliser?

Pour répondre à cette multi-héritage, Java8 fournit les trois règles suivantes:

La priorité de la plus haute priorité méthode des méthodes de la classe, la classe de classe ou d'un parent déclaré en méthode par défaut que toute priorité déclarée.
Si vous ne pouvez pas déterminer d' abord, puis la sous-interface de priorité plus élevée: signatures de méthode sont les mêmes, l'interface a une priorité par défaut choisir la méthode la plus spécifique de mise en œuvre, qui est, si de B A, B est encore plus précis que A.
Enfin, si vous ne pouvez toujours pas juger, plusieurs interfaces classe hérite doit appeler explicitement la couverture souhaitée et les méthodes qui choisissent explicitement de mettre en œuvre une méthode par défaut d'utilisation.
Regardons quelques exemples ensemble.
Scénario 1:

public interface A {
    default void hello() {
        System.out.println("hello from A");
    }
}
public interface B extends A {
    default void hello() {
        System.out.println("hello from B");
    }
}
public class C implements A, B {
    public static void main(String[] args) {
        new C().hello();
    }
}

Insérer ici l'image Description

Nous contrôlons trois règles ci-dessus point de vue, principale méthode de classe C () NUL sortie quoi?

Règle (1)) ne peut être satisfaite.
Depuis de B A, B est la méthode plus spécifique que A, B Bonjour doit être sélectionné (). Ainsi, le programme affichera « bonjour de B ».
Scénario 2:
Si C a hérité d' un tel D comme celui - ci, ce qui se passera?

public class D implements A {

}
public class C extends D implements A, B {
    public static void main(String[] args) {
        new C().hello();
    }
}

Insérer ici l'image Description

De même, nous regardons les trois règles brillantes:

Bien hérité C D, procédé A , mais par défaut D découverte.
Par la suite, le compilateur de choisir A et B, car B Plus précisément, le programme affichera « bonjour de B ».
Scénario 3:
Les modifications ci - dessus D mineures:

public class D implements A {
    public void hello() {
        System.out.println("hello from D");
    }
}

Les résultats et comment?

Parce que, selon les règles (1), a déclaré dans la classe parente a une priorité plus élevée, de sorte que le programme imprimera « bonjour de D ».

Scénario 4:
Supposons maintenant que B ne soit pas hérité A:

public interface A {
    default void hello() {
        System.out.println("hello from A");
    }
}
public interface B {
    default void hello() {
        System.out.println("hello from B");
    }
}
public class C implements A, B {
    public static void main(String[] args) {
        new C().hello();
    }
}

Insérer ici l'image Description

Dans ce cas, car le compilateur ne reconnaît pas atteindre A ou B, plus précisément, il lancera une erreur de compilation: « C defaults sans lien pour bonjour () de types A et B ».

Comme ce scénario pour résoudre le conflit, peuvent être couverts dans la méthode C bonjour () et la méthode de sélection indiqué dans la méthode A ou B de l'appel.

Appel comme suit:

public class C extends D implements A, B {
    public void hello() {
        // 显式地选择调用接口B中的方法
        // 同理,要调用接口A中的方法,可以这样:A.super.hello()
        B.super.hello();
    }

    public static void main(String[] args) {
        // 输出 hello from B
        new C().hello();
    }
}

Scénario 5:

public interface A {
    default void hello() {
        System.out.println("hello from A");
    }
}
public interface B extends A{

}
public interface C extends A{

}
public class D implements B, C {
    public void hello() {
        new D().hello();
    }
}

Insérer ici l'image Description

Dans ce cas, seule une méthode décrite peut être sélectionnée, de sorte que la sortie volonté du programme « bonjour de A ».
Référence:
article , vous reconnaissez prend la méthode par défaut l' interface Java8 en
méthode par défaut Java 8 (par défaut Méthodes)

Publié 80 articles originaux · louange gagné 140 · vues 640 000 +

Je suppose que tu aimes

Origine blog.csdn.net/linjpg/article/details/104117948
conseillé
Classement