Ok, un de mes amis va et vient sur ce que signifie «interface» en programmation.
Quelle est la meilleure description d'une «interface».
Pour moi, une interface est un modèle de classe, est-ce la meilleure définition?
Ok, un de mes amis va et vient sur ce que signifie «interface» en programmation.
Quelle est la meilleure description d'une «interface».
Pour moi, une interface est un modèle de classe, est-ce la meilleure définition?
Réponses:
Une interface est l'un des termes les plus surchargés et déroutants du développement.
C'est en fait un concept d'abstraction et d'encapsulation. Pour une "boîte" donnée, il déclare les "entrées" et les "sorties" de cette boîte. Dans le monde du logiciel, cela signifie généralement les opérations qui peuvent être appelées sur la boîte (avec les arguments) et dans certains cas les types de retour de ces opérations.
Ce qu'il ne fait pas, c'est définir la sémantique de ces opérations, bien qu'il soit courant (et très bonne pratique) de les documenter à proximité de la déclaration (par exemple, via des commentaires), ou de choisir de bonnes conventions de dénomination. Néanmoins, rien ne garantit que ces intentions seront suivies.
Voici une analogie: jetez un œil à votre téléviseur lorsqu'il est éteint. Son interface sont les boutons dont il dispose, les différentes prises et l'écran. Sa sémantique et son comportement sont qu'il prend des entrées (par exemple, programmation par câble) et possède des sorties (affichage à l'écran, son, etc.). Cependant, lorsque vous regardez un téléviseur qui n'est pas branché, vous projetez votre sémantique attendue dans une interface. Pour autant que vous sachiez, le téléviseur pourrait exploser lorsque vous le branchez. Cependant, sur la base de son "interface", vous pouvez supposer qu'il ne fera pas de café car il n'a pas de prise d'eau.
Dans la programmation orientée objet, une interface définit généralement l'ensemble des méthodes (ou messages) auxquels une instance d'une classe disposant de cette interface peut répondre.
Ce qui ajoute à la confusion, c'est que dans certains langages, comme Java, il existe une interface réelle avec sa sémantique spécifique au langage. En Java, par exemple, il s'agit d'un ensemble de déclarations de méthodes, sans implémentation, mais une interface correspond également à un type et obéit à différentes règles de typage.
Dans d'autres langages, comme C ++, vous n'avez pas d'interfaces. Une classe elle-même définit des méthodes, mais vous pouvez considérer l'interface de la classe comme les déclarations des méthodes non privées. En raison de la façon dont C ++ se compile, vous obtenez des fichiers d'en-tête où vous pourriez avoir «l'interface» de la classe sans implémentation réelle. Vous pouvez également imiter les interfaces Java avec des classes abstraites avec des fonctions virtuelles pures, etc.
Une interface n'est certainement pas un modèle pour une classe. Un plan, par définition, est un "plan d'action détaillé". Une interface ne promet rien sur une action! La source de la confusion est que dans la plupart des langages, si vous avez un type d'interface qui définit un ensemble de méthodes, la classe qui l'implémente "répète" les mêmes méthodes (mais fournit une définition), donc l'interface ressemble à un squelette ou à un aperçu de la classe.
Considérez la situation suivante:
Vous êtes au milieu d'une grande pièce vide, quand un zombie vous attaque soudainement.
Vous n'avez pas d'arme.
Heureusement, un autre humain vivant se tient à la porte de la pièce.
"Rapide!" vous lui criez dessus. "Lance-moi quelque chose avec lequel je peux frapper le zombie!"
Considérez maintenant:
vous n'avez pas spécifié (et vous ne vous en souciez pas) exactement ce que votre ami choisira de lancer;
... Mais cela n'a pas d'importance, tant que:
C'est quelque chose qui peut être jeté (il ne peut pas te jeter le canapé)
C'est quelque chose que vous pouvez saisir (espérons qu'il n'a pas jeté un shuriken)
C'est quelque chose que vous pouvez utiliser pour dénigrer le cerveau du zombie (cela exclut les oreillers et autres)
Peu importe que vous ayez une batte de baseball ou un marteau -
tant qu'il met en œuvre vos trois conditions, vous êtes bon.
Résumer:
Lorsque vous écrivez une interface, vous dites en gros: "J'ai besoin de quelque chose qui ..."
L'interface est un contrat que vous devez respecter ou auquel vous devez vous conformer, selon que vous êtes un exécutant ou un utilisateur.
Je ne pense pas que «plan directeur» soit un bon mot à utiliser. Un plan vous explique comment construire quelque chose. Une interface évite spécifiquement de vous dire comment construire quelque chose.
Une interface définit comment vous pouvez interagir avec une classe, c'est-à-dire quelles méthodes elle prend en charge.
Pour moi, une interface est un modèle de classe, est-ce la meilleure définition?
Non. Un plan comprend généralement les éléments internes. Mais une interface concerne uniquement ce qui est visible à l'extérieur d'une classe ... ou plus précisément, une famille de classes qui implémentent l'interface.
L'interface se compose des signatures de méthodes et des valeurs des constantes, ainsi que d'un "contrat comportemental" (généralement informel) entre les classes qui implémentent l'interface et les autres qui l'utilisent.
En programmation, une interface définit le comportement d'un objet, mais elle ne spécifie pas réellement le comportement. C'est un contrat qui garantira qu'une certaine classe peut faire quelque chose.
Considérez ce morceau de code C # ici:
using System;
public interface IGenerate
{
int Generate();
}
// Dependencies
public class KnownNumber : IGenerate
{
public int Generate()
{
return 5;
}
}
public class SecretNumber : IGenerate
{
public int Generate()
{
return new Random().Next(0, 10);
}
}
// What you care about
class Game
{
public Game(IGenerate generator)
{
Console.WriteLine(generator.Generate())
}
}
new Game(new SecretNumber());
new Game(new KnownNumber());
La classe Game nécessite un numéro secret. Pour le tester, vous souhaitez injecter ce qui sera utilisé comme numéro secret (ce principe est appelé Inversion de Contrôle).
La classe de jeu veut être "ouverte d'esprit" sur ce qui créera réellement le nombre aléatoire, donc elle demandera dans son constructeur "tout ce qui a une méthode Generate".
Tout d'abord, l'interface spécifie les opérations qu'un objet fournira. Il contient juste à quoi il ressemble, mais aucune implémentation réelle n'est donnée. Ce n'est que la signature de la méthode. De manière conventionnelle, les interfaces en C # sont précédées d'un I. Les classes implémentent désormais l'interface IGenerate. Cela signifie que le compilateur s'assurera qu'ils ont tous les deux une méthode qui renvoie un int et qui est appelée Generate
. Le jeu est maintenant appelé deux objets différents, chacun implémentant l'interface correcte. D'autres classes produiraient une erreur lors de la construction du code.
Ici, j'ai remarqué l'analogie du plan que vous avez utilisée:
Une classe est généralement considérée comme un modèle pour un objet. Une interface spécifie quelque chose qu'une classe devra faire, donc on pourrait dire qu'il ne s'agit en fait que d'un modèle pour une classe, mais comme une classe n'a pas nécessairement besoin d'une interface, je dirais que cette métaphore est en train de se rompre. Considérez une interface comme un contrat. La classe qui «signe» sera légalement tenue (imposée par la police du compilateur) de se conformer aux termes et conditions du contrat. Cela signifie qu'il devra faire ce qui est spécifié dans l'interface.
Tout cela est dû à la nature statiquement typée de certains langages OO, comme c'est le cas avec Java ou C #. En Python par contre, un autre mécanisme est utilisé:
import random
# Dependencies
class KnownNumber(object):
def generate(self):
return 5
class SecretNumber(object):
def generate(self):
return random.randint(0,10)
# What you care about
class SecretGame(object):
def __init__(self, number_generator):
number = number_generator.generate()
print number
Ici, aucune des classes n'implémente d'interface. Python ne se soucie pas de cela, parce que la SecretGame
classe essaiera simplement d'appeler n'importe quel objet passé. Si l'objet A une méthode generate (), tout va bien. Si ce n'est pas le cas: KAPUTT! Cette erreur ne sera pas vue au moment de la compilation, mais au moment de l'exécution, donc peut-être lorsque votre programme est déjà déployé et en cours d'exécution. C # vous avertirait bien avant que vous ne vous approchiez de cela.
La raison pour laquelle ce mécanisme est utilisé, naïvement déclaré, parce que dans les langues OO, les fonctions ne sont naturellement pas des citoyens de première classe. Comme vous pouvez le voir, KnownNumber
etSecretNumber
contiennent JUSTE les fonctions pour générer un nombre. On n'a pas vraiment besoin des cours du tout. En Python, par conséquent, on pourrait simplement les jeter et choisir les fonctions seules:
# OO Approach
SecretGame(SecretNumber())
SecretGame(KnownNumber())
# Functional Approach
# Dependencies
class SecretGame(object):
def __init__(self, generate):
number = generate()
print number
SecretGame(lambda: random.randint(0,10))
SecretGame(lambda: 5)
Un lambda est juste une fonction, qui a été déclarée "en ligne, au fur et à mesure". Un délégué est exactement le même en C #:
class Game
{
public Game(Func<int> generate)
{
Console.WriteLine(generate())
}
}
new Game(() => 5);
new Game(() => new Random().Next(0, 10));
Remarque: les derniers exemples n'étaient pas possibles comme ça jusqu'à Java 7. Là, les interfaces étaient votre seul moyen de spécifier ce comportement. Cependant, Java 8 a introduit des expressions lambda afin que l'exemple C # puisse être converti en Java très facilement ( Func<int>
devient java.util.function.IntSupplier
et =>
devient ->
).
Techniquement, je décrirais une interface comme un ensemble de façons (méthodes, propriétés, accesseurs ... le vocabulaire dépend de la langue que vous utilisez) pour interagir avec un objet. Si un objet prend en charge / implémente une interface, vous pouvez utiliser toutes les méthodes spécifiées dans l'interface pour interagir avec cet objet.
Sémantiquement, une interface peut également contenir des conventions sur ce que vous pouvez ou ne pouvez pas faire (par exemple, l'ordre dans lequel vous pouvez appeler les méthodes) et sur ce que, en retour, vous pouvez supposer sur l'état de l'objet étant donné la façon dont vous avez interagi. loin.
Personnellement, je vois une interface comme un modèle. Si une interface contient la définition des méthodes foo () et bar (), alors vous savez que chaque classe qui utilise cette interface a les méthodes foo () et bar ().
Prenons l'exemple d'un homme (utilisateur ou objet) qui souhaite faire du travail. Il contactera un intermédiaire (Interface) qui aura un contrat avec les entreprises (objets du monde réel créés à l'aide de classes implémentées). Peu de types d'ouvrages seront définis par lui, quelles entreprises mettront en œuvre et lui donneront des résultats. Chaque entreprise mettra en œuvre le travail à sa manière, mais le résultat sera le même. Comme cet utilisateur fera son travail en utilisant une seule interface. Je pense que l'interface agira comme une partie visible des systèmes avec peu de commandes qui seront définies en interne par les sous-systèmes internes implémentés.
Une interface sépare les opérations sur une classe de l'implémentation à l'intérieur. Ainsi, certaines implémentations peuvent fournir de nombreuses interfaces.
Les gens le décriraient généralement comme un «contrat» pour ce qui doit être disponible dans les méthodes de la classe.
Ce n'est absolument pas un plan, car cela déterminerait également la mise en œuvre. Une définition de classe complète pourrait être considérée comme un modèle.
Une interface définit ce qu'une classe qui en hérite doit implémenter. De cette façon, plusieurs classes peuvent hériter d'une interface, et en raison de cet héritage, vous pouvez
pour plus d'informations, consultez ce http://msdn.microsoft.com/en-us/library/ms173156.aspx
À mon avis, l'interface a une signification plus large que celle qui lui est généralement associée en Java. Je définirais "interface" comme un ensemble d'opérations disponibles avec des fonctionnalités communes, qui permettent de contrôler / surveiller un module.
Dans cette définition, j'essaie de couvrir à la fois les interfaces programmatiques, où le client est un module, et les interfaces humaines (GUI par exemple).
Comme d'autres l'ont déjà dit, une interface a toujours un contrat derrière elle, en termes d'entrées et de sorties. L'interface ne promet rien sur le «comment» des opérations; il ne garantit que certaines propriétés du résultat, compte tenu de l'état actuel, de l'opération sélectionnée et de ses paramètres.
Comme ci-dessus, les synonymes de «contrat» et de «protocole» sont appropriés.
L'interface comprend les méthodes et les propriétés que vous pouvez vous attendre à voir exposées par une classe.
Donc, si une classe Cheetos Bag
implémente l' Chip Bag
interface, vous devriez vous attendre Cheetos Bag
à ce que a se comporte exactement comme les autres Chip Bag
. (Autrement dit, exposez la .attemptToOpenWithoutSpillingEverywhere()
méthode, etc.)
Définition conventionnelle - Une interface est un contrat qui spécifie les méthodes qui doivent être implémentées par la classe qui l'implémente.
La définition de l'interface a changé au fil du temps. Pensez-vous que l'interface n'a que des déclarations de méthode? Qu'en est-il des variables finales statiques et des définitions par défaut après Java 5.
Les interfaces ont été introduites dans Java en raison du problème Diamond avec l'héritage multiple et c'est ce qu'elles ont réellement l'intention de faire.
Les interfaces sont les constructions qui ont été créées pour résoudre le problème d'héritage multiple et peuvent avoir des méthodes abstraites, des définitions par défaut et des variables finales statiques.
Une frontière à travers laquelle deux systèmes communiquent.
Les interfaces permettent à certains langages OO de réaliser un polymorphisme ad hoc . Le polymorphisme ad hoc est simplement des fonctions avec les mêmes noms opérant sur différents types.
En bref, le problème de base qu'une interface essaie de résoudre est de séparer la façon dont nous utilisons quelque chose de la façon dont il est implémenté. Mais vous devez considérer que l'interface n'est pas un contrat . En savoir plus ici .