Astuce Java #2 : abstract et final vs interface et enum

Nouvelle question existentielle (je commence à croire que les questions nous viennent au rythme de une par jour en ce moment...).

Ce fois ci : Quelles sont les combinaisons possible en mélangeant les mots clés abstract et final avec les mots clés interface et enum ?

On pourrait résumer l'intégralité de cette question de cette manière :
Lesquelles de ces différentes combinaisons de mots clés sont autorisées pour déclarer un type ?
abstract final
interface ? ?
enum ? ?

Voici ce à quoi on aurait pu s'attendre :
abstract final
interface Illégal Légal
enum Légal Illégal

Je m'explique :
  • Une interface est par définition abstraite, abstract serait donc bien absurde dans ce cas.
  • Une interface pourrait être finale comme les classes le sont pour interdire l'héritage. On pourrait donc continuer à implémenter une interface, mais on ne pourrait pas en hériter (pour rappel, une interface hérite d'une autre).
  • Une énumération peut contenir des méthodes. Donc pourquoi pas des méthodes abstraites ?
  • Les types "enum" se sont pas extensibles (on ne peut pas les hériter), donc un final ici serait absurde une fois de plus.

Et bien voilà, après tests, ce que l'on obtient :
abstract final
interface Légal Illégal
enum Illégal Illégal

Trois surprises :
  • Il est possible de rendre une interface abstraite. Le comportement de l'interface n'est en rien modifié. D'après la Java Language Specification (Third edition), § 9.1.1.1 :
    Every interface is implicitly abstract. This modifier is obsolete and should not be used in new programs.
    The Java Language Specification, Third Edition, § 9.1.1.1
  • Il n'est pas possible de rendre une interface finale.
  • Il n'est pas possible de mettre des méthodes abstraites dans une énumération.

Je m'attendais pas vraiment à ces résultats, je vais retourner traîner à la recherche d'une explication sur ces points (car explication il doit y avoir).

Permalink  |  Commentaires (1)

Astuce Java #1 : Multi-héritage d'interface

Encore une question existentielle née d'un débat passionné entre Colin et moi. La question cette fois-ci :
Est-ce qu'une interface peut hériter de plusieurs autres interfaces ?
Colin

Question justifiée par les faits suivants :
  • Une classe ne peut hériter que d'une seule autre classe
  • Une classe peut implémenter plusieurs interfaces
  • Une interface hérite d'une autre interface, et n'implémente pas une autre interface

Il semblerais logique que oui, une interface puisse hériter de plusieurs autres interfaces.

Après tests, la logique l'emporte. Une interface peut hériter de plusieurs autres interfaces. Le code suivant est entièrement valide :
package multiextendsinterface;

interface A { public void a(); }
interface B { public void b(); }
interface C extends A, B { public void c(); }

public class Main {
    public static void main(String[] args) {
        C c = new C() {
            public void a() { System.out.println("a"); }
            public void b() { System.out.println("b"); }
            public void c() { System.out.println("c"); }
        };
        c.a();
        c.b();
        c.c();
    }
}
Et la sortie sera la suivante :
a
b
c

A noter dans mon calepin de "choses à se souvenir" : une interface peut bel et bien hériter de plusieurs autres interfaces.

Permalink  |  Commentaires (0)