Le sujet en dit le plus - quelle est la raison pour laquelle les méthodes statiques ne peuvent pas être déclarées dans une interface?
public interface ITest {
public static String test();
}
Le code ci-dessus me donne l'erreur suivante (dans Eclipse, au moins): "Modificateur illégal pour la méthode d'interface ITest.test (); seuls public & abstract sont autorisés".
Réponses:
Il y a quelques problèmes en jeu ici. Le premier est le problème de la déclaration d'une méthode statique sans la définir. C'est la différence entre
et
La première est impossible pour les raisons mentionnées par Espo : vous ne savez pas quelle classe d'implémentation est la bonne définition.
Java pourrait permettre ce dernier; et en fait, à partir de Java 8, c'est le cas!
la source
static
méthodes dans un fichierinterface
. Les méthodes doivent êtrepublic
.La raison pour laquelle vous ne pouvez pas avoir de méthode statique dans une interface réside dans la façon dont Java résout les références statiques. Java ne prendra pas la peine de rechercher une instance d'une classe lors d'une tentative d'exécution d'une méthode statique. En effet, les méthodes statiques ne dépendent pas de l'instance et peuvent donc être exécutées directement à partir du fichier de classe. Étant donné que toutes les méthodes d'une interface sont abstraites, la machine virtuelle devrait rechercher une implémentation particulière de l'interface afin de trouver le code derrière la méthode statique afin qu'elle puisse être exécutée. Cela contredit alors le fonctionnement de la résolution de méthode statique et introduirait une incohérence dans le langage.
la source
Je répondrai à votre question par un exemple. Supposons que nous ayons une classe Math avec une méthode statique add. Vous appelleriez cette méthode comme ceci:
Si Math était une interface au lieu d'une classe, il ne pourrait pas avoir de fonctions définies. En tant que tel, dire quelque chose comme Math.add (2, 3) n'a aucun sens.
la source
La raison réside dans le principe de conception, que java ne permet pas l'héritage multiple. Le problème de l'héritage multiple peut être illustré par l'exemple suivant:
Maintenant, que se passe-t-il si vous appelez Cx ()? Est-ce que Ax () ou Bx () sera exécuté? Chaque langue à héritage multiple doit résoudre ce problème.
Les interfaces permettent en Java une sorte d'héritage multiple restreint. Pour éviter le problème ci-dessus, ils ne sont pas autorisés à avoir des méthodes. Si nous regardons le même problème avec les interfaces et les méthodes statiques:
Même problème ici, que se passe-t-il si vous appelez Cx ()?
la source
A
contiennentint x(int z);
et de l' interfaceB
contiennentstring x(int x);
? Quelle est la signification dex(3)
dans l'interface C?Les méthodes statiques ne sont pas des méthodes d'instance. Il n'y a pas de contexte d'instance, donc l'implémenter à partir de l'interface n'a pas de sens.
la source
Maintenant, Java8 nous permet de définir même des méthodes statiques dans l'interface.
Remarque: les méthodes dans Interface sont toujours publiques abstraites par défaut si nous n'utilisons pas explicitement les mots-clés default / static pour en faire des méthodes par défaut et des méthodes statiques resp.
la source
Il y a une réponse très agréable et concise à votre question ici . (Cela m'a frappé comme une façon si simple de l'expliquer que je veux le lier à partir d'ici.)
la source
Il semble que la méthode statique de l'interface puisse être prise en charge dans Java 8 , eh bien, ma solution consiste simplement à les définir dans la classe interne.
La même technique peut également être utilisée dans les annotations:
La classe interne doit toujours être accédée sous la forme
Interface.fn...
au lieu deClass.fn...
, alors, vous pouvez vous débarrasser du problème ambigu.la source
Une interface est utilisée pour le polymorphisme, qui s'applique aux objets, pas aux types. Par conséquent (comme déjà noté) cela n'a aucun sens d'avoir un membre d'interface statique.
la source
Java 8 Avait changé le monde, vous pouvez avoir des méthodes statiques dans l'interface, mais cela vous oblige à fournir une implémentation pour cela.
}
la source
Combinaison illégale de modificateurs: statique et abstrait
Si un membre d'une classe est déclaré statique, il peut être utilisé avec son nom de classe qui est confiné à cette classe, sans créer d'objet.
Si un membre d'une classe est déclaré comme abstrait, vous devez déclarer la classe comme abstrait et vous devez fournir l'implémentation du membre abstrait dans sa classe héritée (sous-classe).
Vous devez fournir une implémentation au membre abstrait d'une classe dans une sous-classe où vous allez changer le comportement de la méthode statique, également déclarée comme abstraite qui est confinée à la classe de base, ce qui n'est pas correct
la source
Puisque les méthodes statiques ne peuvent pas être héritées. Donc inutile de le placer dans l'interface. L'interface est essentiellement un contrat que tous ses abonnés doivent suivre. Placer une méthode statique dans l'interface forcera les abonnés à l'implémenter. ce qui devient désormais contradictoire avec le fait que les méthodes statiques ne peuvent pas être héritées.
la source
Par exemple, Comparator a une méthode statique naturalOrder ().
L'exigence selon laquelle les interfaces ne peuvent pas avoir d'implémentations a également été assouplie. Les interfaces peuvent maintenant déclarer des implémentations de méthode "par défaut", qui sont comme des implémentations normales à une exception près: si vous héritez à la fois d'une implémentation par défaut d'une interface et d'une implémentation normale d'une superclasse, l'implémentation de la superclasse sera toujours prioritaire.
la source
Peut-être qu'un exemple de code pourrait vous aider, je vais utiliser C #, mais vous devriez pouvoir suivre.
Supposons que nous ayons une interface appelée IPayable
Maintenant, nous avons deux classes concrètes qui implémentent cette interface:
Maintenant, faisons comme si nous avons une collection de différents comptes, pour ce faire nous utiliserons une liste générique du type IPayable
Maintenant, nous voulons payer 50,00 $ à tous ces comptes:
Alors maintenant, vous voyez à quel point les interfaces sont incroyablement utiles.
Ils sont utilisés uniquement sur les objets instanciés. Pas sur les classes statiques.
Si vous aviez rendu le paiement statique, lors de la lecture en boucle de l'IPayable dans accountsToPay, il n'y aurait aucun moyen de savoir s'il devrait appeler le paiement sur BusinessAcount ou CustomerAccount.
la source