Personnellement, les soi-disant classes de programmation sont le même concept que les classes du monde réel qui classent les objets, mais elles sont empruntées en programmation. Les classes représentent des choses qui ont une série de points communs et les mêmes opérations ou actions, qui sont des types de données abstraits en programmation. Chaque individu spécifique (dans le monde réel) et les variables d'instance (pour la programmation) sont des objets.
Une classe est une représentation de caractéristiques communes (attributs et opérations) de certains objets dans le monde réel, et un objet est une instance d'une classe.
Attributs de classe: est l'abréviation des attributs statiques d'une classe, qui fait référence à diverses données contenues dans la classe, telles que des variables ou d'autres objets de classe;
Un service de classe: est appelé une fonction ou une méthode membre.
¨
La forme de définition d'une classe en Java est la suivante:
[Modificateur] Nom de classe de classe [étend la classe parent] [implémente le nom de l'interface] {classe de la classe de la variable de la Classe Méthode de classe de classe}Parlons de chaque partie de cela en détail:
Avant le mot-clé de classe, les modificateurs de classe sont généralement divisés en trois types: les modificateurs d'accès public public, le modificateur final (spécificateur de classe finale) et le modificateur abstrait (spécificateur de classe abstrait)
Parmi eux, le modificateur d'autorisation ne peut être que public ou par défaut (c'est-à-dire vide, rien, indiquant qu'il est défini comme amical), et le public signifie que la classe peut être utilisée et accessible n'importe où (tant que le programme peut trouver l'emplacement de la classe), que ce soit dans le même package ou dans différents paquets. Notez que cela est différent de C ++. C ++ n'a pas de modificateur pour restreindre les droits d'accès à la classe, mais a plutôt des droits d'accès aux relations successives entre les classes. De plus, ils ont tous des droits d'accès aux attributs et méthodes de classe. L'autorisation d'accès par défaut (c'est-à-dire définie comme amicale) signifie qu'elle ne peut être référencée et accessible par les classes du même package, mais ne peut pas être consultée et référencée par des classes dans d'autres packages, même s'ils sont importés.
Il sera également mentionné plus loin: lorsque le modificateur par défaut d'un attribut et d'une méthode de classe sera utilisé, il est également exprimé qu'il ne peut être référencé et accessible que par des classes du même package.
L'héritage multiple n'est pas autorisé dans Java, qui est différent de C ++. Afin de compenser cette lacune, Java a introduit le concept d'interface.
Dans la définition de la classe ci-dessus, le corps de classe contient principalement le contenu spécifique de la classe, y compris les attributs de la classe et les méthodes de la classe. Les propriétés d'une classe peuvent être des variables simples ou des instances de certaines classes. S'il s'agit d'une instance d'une classe, il peut être défini comme suit:
[Modificateur] Nom de classe Nom de l'objet = nouveau nom de classe (liste de paramètres);
Lorsque vous déclarez des objets et des variables complexes, vous ne pouvez pas utiliser la création pendant les déclarations, mais vous pouvez être créée dans les futurs constructeurs.
Les méthodes définies dans une classe jouent généralement deux rôles: l'une consiste à effectuer diverses opérations autour des attributs de la classe; L'autre consiste à effectuer l'échange de données, la livraison de messages et d'autres opérations avec d'autres classes ou objets.
La syntaxe des méthodes de déclaration en Java est la suivante:
[Modificateur] Retour du type de valeur Nom de la méthode (Liste des paramètres) Nom de l'exception 1, Nom de l'exception 2,… {Méthode Body: Déclaration de variable locale; séquence de déclaration;}Les méthodes de classe, également appelées fonctions membres, sont utilisées pour spécifier les opérations sur les attributs de classe et implémenter les fonctions internes des classes. Ils sont également une fenêtre importante pour les classes pour interagir avec le monde extérieur.
Les programmeurs Java se concentrent sur la création de types définis par l'utilisateur appelées classes. Les classes sont également appelées types définis par le programmeur. Chaque classe contient des données et un ensemble de méthodes de manipulation de données. La partie de données de la classe est appelée variables d'instance. Une instance d'un type défini par l'utilisateur (c'est-à-dire une classe) est appelée objet.
Un objet est une instance d'une classe. Une classe est une abstraction du même type d'objet et un modèle pour créer un objet. La création d'un objet dans le programme ouvrira un espace en mémoire, y compris les propriétés et les méthodes de l'objet. Créez un objet à l'aide de l'opérateur de mots clés Nouveau.
Constructeur (peut être comparé à C ++, qui est presque le même que C ++)
Créez votre propre constructeur
• Le nom du constructeur et le nom de la classe sont les mêmes. Lors de la construction d'un objet de la classe Employee, ce constructeur est démarré et le champ d'instance se voit attribuer une valeur initiale. En Java, la définition et l'initialisation sont unifiées - les deux sont indispensables.
Par exemple, lors de la création d'une instance de la classe des employés avec le code suivant,
NewEmployee ("James Bond", 100000,1950,1,1);
Les caractéristiques du constructeur sont:
(1) Le constructeur et la classe ont le même nom.
(2) Une classe peut avoir plusieurs constructeurs.
(3) Le constructeur peut avoir 0, 1 ou plus des paramètres.
(4) Le constructeur n'a aucune valeur de retour.
(5) Le constructeur est toujours appelé avec le nouvel opérateur.
Le rôle du constructeur
(1) Initialisation de l'objet
(2) introduire plus de flexibilité (affectation variable ou opérations plus complexes)
(3) le constructeur ne peut pas être défini en java
Un constructeur ne peut pas être défini en Java et le système générera automatiquement un constructeur par défaut pour le système. Le nom de ce constructeur est le même que le nom de classe, il n'a pas de paramètres formels et n'effectue aucune opération.
Présentation de la méthode
Un programme Java est composé de définitions de classe, et la classe a deux parties: les propriétés et les méthodes. Qu'est-ce qu'une classe de description d'attribut et ce que fait une classe de description de méthode. Tout objet a une mémoire indépendante pour stocker ses propriétés. Tous les objets de la classe partagent la méthode stockée en mémoire.
En d'autres termes: les méthodes sont le composant principal de la classe. Dans une classe, le rôle d'un programme se reflète dans la méthode.
La méthode consiste à créer un sous-programme nommé par Java. Une méthode principale et plusieurs sous-méthodes. La méthode principale appelle d'autres méthodes et d'autres méthodes peuvent également être appelées les unes aux autres, et la même méthode peut être appelée à tout moment par une ou plusieurs méthodes.
La définition d'une autre méthode dans une méthode produira une erreur de syntaxe.
(1) Il est préférable d'éviter les variables locales "masque" les variables d'instance. Cela peut être fait sans utiliser l'identifiant du même nom dans une classe; Les paramètres des appels de méthode sont utilisés pour transmettre des valeurs et des références numériques, et les méthodes peuvent également être appelées dans les imbriquées et récursivement.
(2) Si un type de valeur de retour non-VOID est spécifié dans le corps de la méthode, la méthode doit inclure une instruction de retour pour s'assurer qu'il existe une valeur de retour dans tous les cas et l'instruction de retour ne peut être suivie d'une expression;
La structure de base des programmes Java est la suivante:
Présenter la bibliothèque de classe Java; Définir l'utilisateur Classe 1 {Définir plusieurs variables ou objets de la classe 1: Définissez la méthode 1 de la classe 1; définir la méthode 2 de la classe 1; … Définissez la méthode M1 de la classe 1; } Définir l'utilisateur Classe 2 {Définir plusieurs variables ou objets de la classe 2: Définissez la méthode 1 de la classe 2; définir la méthode 2 de la classe 2; … Définissez la méthode M2 de la classe 2}Java a introduit le concept de "modificateur de contrôle d'accès" qui permet aux créateurs de bibliothèques de déclarer ce qui peut être utilisé par les programmeurs clients et ce qui ne peut pas être utilisé.
Ce niveau de contrôle d'accès se situe entre la plage de "Accès maximum" et "Accès minimum", y compris: public, "par défaut" (pas de mot-clé), protégé et privé. La liste suivante explique la signification des modificateurs de contrôle d'accès:
Personnage du public à l'accès à l'accès
Pour les cours:
Il n'y a qu'un seul contrôleur d'accès pour une classe en Java: public, c'est-à-dire public. Une classe est déclarée comme une classe publique, indiquant qu'elle peut être accessible et référencée par toutes les autres classes. L'accès et la référence ici se réfèrent à la classe visible et utilisable dans son ensemble. D'autres parties du programme peuvent créer des objets de cette classe, accéder aux variables des membres visibles à l'intérieur de la classe et appeler ses méthodes visibles.
Une classe est visible par d'autres parties du programme dans son ensemble et ne représente pas que toutes les propriétés et méthodes de la classe sont également visibles dans d'autres parties du programme. Le premier n'est qu'une condition nécessaire pour la seconde. La question de savoir si les propriétés et les méthodes de la classe peuvent être accessibles par toutes les autres classes dépend des caractères de contrôle d'accès de ces propriétés et méthodes.
Utilisé pour les propriétés en classe:
Les attributs en classe modifiés avec le public sont appelés attributs publics. Si cette classe est une classe publique, elle est accessible par toutes les autres classes.
Contrôle d'accès par défaut
Utilisé pour les cours
Si une classe n'a pas de caractères de contrôle d'accès, cela signifie qu'il a les caractéristiques de contrôle d'accès par défaut. Ce contrôle d'accès par défaut stipule que la classe ne peut être accessible et référencée par les classes du même package, et ne peut pas être utilisée par les classes dans d'autres packages. Cette fonction d'accès est appelée accessibilité du package. En déclarant les caractères de contrôle d'accès de la classe, toute la structure du programme peut être claire et rigoureuse, réduisant les interférences et les erreurs inter-classes possibles.
Utilisé pour les attributs de classe
Si les propriétés et les méthodes de la classe ne sont pas limitées par les symboles de contrôle d'accès, ils indiquent également qu'ils sont l'accessibilité des paquets.
3 personnage de contrôle d'accès privé privé
Les attributs ou méthodes modifiés avec privé ne peuvent être accessibles et modifiés par la classe elle-même, et ne peuvent être obtenues et référencées par aucune autre classe, y compris les sous-classes de la classe.
1). Les données privées, par exemple, possèdent trois champs d'instructions, qui contiennent des données qui fonctionnent dans une instance de la classe des employés.
nom de chaîne privé;
Salaire double privé;
Date privée Hireday;
Le mot-clé privé est utilisé pour s'assurer que ces champs d'instance ne peuvent être accessibles que par la classe des employés lui-même.
2). Private Méthode Lors de la mise en œuvre de la classe, nous rendons tous les champs de données privés car les données publiques sont dangereuses. Quelle est la situation avec la méthode? Bien que la plupart des méthodes soient publiques, les méthodes privées sont également fréquemment utilisées. Ces méthodes ne peuvent être séparées que par la même méthode.
En bref, la méthode privée peut être sélectionnée dans les cas suivants:
(1) les méthodes qui ne sont pas liées à l'utilisateur de la classe.
(2) les méthodes qui ne sont pas faciles à maintenir si la mise en œuvre de la classe est modifiée.
Caractère de contrôle d'accès protégé protégé
Les variables membre modifiées avec protégé peuvent être référencées par trois types: la classe elle-même, d'autres classes dans le même package qu'elle et les sous-classes de la classe dans d'autres packages. L'objectif principal de l'utilisation du modificateur protégé est d'autoriser ses sous-classes dans d'autres packages pour accéder aux propriétés spécifiques de la classe parent.
Le mot-clé protégé nous présente un concept appelé "héritage", qui est basé sur des classes existantes et y ajoute de nouveaux membres sans affecter les classes existantes - nous appelons cette classe existante "classe de base" ou "classe de base". Il peut également modifier le comportement des membres existants de cette classe. Pour l'héritage d'une classe existante, nous disons que notre nouvelle classe "étend" la classe existante
Caractère de contrôle d'accès protégé privé Private protégé
Les privés et protégés sont utilisés en séquence pour former un caractère complet de contrôle d'accès: le caractère de contrôle d'accès à protection privée. Les variables membre modifiées avec Private Protected peuvent être consultées et référencées par deux classes, l'une est la classe elle-même, et l'autre est toutes les sous-classes de la classe, que ces sous-classes soient dans le même package que la classe ou dans d'autres packages.
Par rapport à Protected, le modificateur ProDetecd Private exclut les non-sous-classes dans le même package à partir de la portée accessible, rendant les variables membres plus propriétaires aux classes avec des relations d'héritage explicites plutôt que des packages qui sont lâchement regroupés.
Modificateur statique
Static est appelé modificateur statique, qui modifie les propriétés et les méthodes dans une classe.
L'utilisation du mot-clé statique peut répondre à deux exigences:
(1) Une situation est que vous souhaitez uniquement utiliser une zone de stockage pour enregistrer des données spécifiques - peu importe le nombre d'objets que vous souhaitez créer, vous ne créez même pas du tout des objets; Les attributs modifiés par statique sont appelés propriétés statiques, et l'une des caractéristiques les plus essentielles de ce type d'attribut est qu'ils sont des attributs d'une classe, et non des objets spécifiques d'une classe. En d'autres termes, pour tout objet spécifique de cette classe, une propriété statique est une unité de stockage commune. Lorsqu'un objet d'une classe y accède, il obtient la même valeur numérique. Lorsqu'un objet d'une classe le modifie, il fait également des opérations sur la même unité de mémoire.
(2) Une autre situation est que nous avons besoin d'une méthode spéciale qui n'est associée à aucun objet de cette classe. C'est-à-dire, même si l'objet n'est pas créé, une méthode qui peut être appelée directement par la classe est nécessaire.
Un objectif important de la statique est de nous aider à appeler cette méthode sans avoir à créer un objet.
Constantes statiques
Les variables statiques sont rares. Cependant, les constantes statiques sont courantes. Par exemple, une constante statique est définie dans la classe de mathématiques:
mathématiques de classe publique
{… Public statique final Double Pi = 3.1.4159265358979323846;…} Une méthode statique déclare qu'une méthode est statique a au moins trois significations:
(1) Lorsque vous utilisez cette méthode, le nom de classe doit être utilisé comme préfixe, plutôt que comme un nom d'objet spécifique;
(2) Les méthodes non statiques sont des méthodes appartenant à un objet. Lorsque cet objet est créé, la méthode de l'objet a son propre segment de code dédié en mémoire; tandis que la méthode statique appartient à toute la classe, et son segment de code en mémoire sera alloué et chargé en fonction de la définition de la classe et ne sera exclusif à aucun objet;
(3) Étant donné que la méthode statique appartient à la classe entière, elle ne peut pas manipuler et traiter les variables des membres appartenant à un certain objet, mais ne peut traiter que des variables membre appartenant à toute la classe.
5 méthode principale
La méthode principale n'applique pas les opérations à aucun objet. En fait, lorsque le programme commence à s'exécuter, aucun objet n'existe encore. La méthode statique est exécutée et les objets requis par le programme sont construits.
Il invite que chaque classe peut avoir une méthode principale. Il s'agit d'une astuce très pratique pour les classes de test unitaires.
Résumé est un modificateur abstrait qui peut être utilisé pour modifier les classes ou les méthodes.
Classe abstraite
Lorsqu'une classe est déclarée abstraite, cette classe est appelée une classe abstraite. La classe dite abstraite est une classe sans objets d'instance concrète.
Pour résoudre ce problème, Java fournit un mécanisme appelé "méthode abstraite". Il appartient à une méthode incomplète, avec une seule déclaration, et n'a pas de corps de méthode. Voici la syntaxe utilisée lors de la déclaration des méthodes abstraites:
abstrait vide x ();
Méthodes abstraites
En tant que modificateur de méthode de classe, le résumé déclare une méthode abstraite qui n'a que des en-têtes de méthode mais aucune implémentation spécifique du corps et de l'opération.
On peut voir que la méthode abstraite n'a que la déclaration de l'en-tête de la méthode, et un point-virgule est utilisé pour remplacer la définition du corps de la méthode: quant à l'implémentation spécifique du corps de la méthode, il est complété par différentes sous-classes de la classe actuelle dans leurs définitions de classe respectives.
Il convient de noter que toutes les méthodes abstraites doivent exister dans les classes abstraites
milieu.
En plus des méthodes abstraites, les classes abstraites peuvent également avoir des données et des méthodes concrètes.
Les méthodes abstraites sont des concepts très importants dans le langage de programmation Java. Vous l'utiliserez à bien des égards dans l'interface.
Remarque: Ici, nous devons comparer et mémoriser avec l'interface. Les méthodes de l'interface sont toutes des méthodes abstraites. Bien sûr, il existe également des attributs dans l'interface, et leurs propriétés spécifiques seront décrites en détail plus tard.
Classe finale, attribut final, méthode finale et finalisateur (il n'y a pas de modificateur final en C ++)
Final est le modificateur final, qui modifie les classes, les propriétés et les méthodes. De plus, les mots clés du terminal sont très similaires à Final et seront introduits ensemble
Classe finale
Si une classe est déclarée finale, cela signifie qu'elle ne peut pas dériver de nouvelles sous-classes et ne peut pas être héritée en tant que classe parent. Par conséquent, une classe ne peut pas être déclarée à la fois abstraite et finale.
Les classes définies comme finales sont généralement certaines classes avec des fonctions spéciales qui sont utilisées pour remplir des fonctions standard. La définition d'une classe en tant que final peut corriger son contenu, ses attributs et ses fonctions et former une relation de mappage stable avec son nom de classe, garantissant ainsi que les fonctions implémentées lors de la référence à cette classe sont exactes.
Attributs finaux
De nombreux langages de programmation ont leurs propres façons de dire au compilateur que certaines données sont une "constante". Les constantes sont principalement utilisées dans les deux aspects suivants:
(1) Période de compilation constante, elle ne changera jamais;
(2) Nous ne voulons pas qu'une valeur initialisée pendant le temps d'exécution change.
Un champ d'instance peut être défini comme final (ne peut pas être modifié). Ce champ doit être initialisé lorsque l'objet est construit. Autrement dit, il faut s'assurer que la valeur a été définie avant la fin de chaque constructeur. La valeur du champ ne peut pas être modifiée à l'avenir
Méthode finale
La raison de l'utilisation de la méthode finale peut être due à des considérations pour deux raisons.
La première consiste à "verrouiller" la méthode pour empêcher toute classe d'héritage de modifier sa signification d'origine. Lors de la conception d'un programme, cette pratique peut être prise si vous voulez que le comportement d'une méthode reste inchangé pendant l'héritage et ne peut pas être écrasé ou réécrit.
La deuxième raison d'adopter la méthode finale est l'efficacité de l'exécution du programme
Terminateur
La fonction du terminateur est une méthode exécutée lors de la récupération des objets. Semblable à la méthode que les constructeurs sont exécutés lors de la création d'objets.
exemple
protégé voidFinalize () {System.out.println (""); }Autres modificateurs
volatil
Si un attribut est modifié par un volatil, cela signifie que cet attribut peut être contrôlé et modifié par plusieurs threads en même temps.
synchronisé
Principalement utilisé pour la synchronisation du thread
indigène
Cela signifie que la méthode n'est pas écrite en langue java (elle est écrite en C, C ++ et d'autres langues)
Quelques informations trouvées en ligne: - catégorie interne
Autrement dit, les classes internes sont des classes dans les classes, par exemple:
classe A {private int i; private void m () {} classe b {mm (int j) {i = j; m ();}}}Ici, B est la classe interne de A, caractérisée par un accès pratique aux méthodes et propriétés privées dans les classes externes. Par exemple, ici B peut accéder directement aux propriétés privées I et aux méthodes privées m () dans A.
Les caractéristiques les plus importantes de la programmation orientée objet sont l'encapsulation (également appelée abstraction), l'héritage et le polymorphisme. En tant que langage de programmation orienté objet, Java a ses propres avantages à cet égard:
"L'héritage est une forme de réutilisation des logiciels, qui est efficace pour réduire la complexité des logiciels. L'héritage est également une caractéristique d'un langage de programmation orienté objet. Les langages qui adoptent des objets mais n'ont pas d'hérédité sont des langages basés sur des objets, mais pas des langages orientés objet. C'est la différence entre les deux."
La relation d'héritage entre les classes est une simulation directe des relations génétiques dans le monde réel. Il représente la connexion intrinsèque entre les classes et le partage des attributs et des opérations, c'est-à-dire que les sous-classes peuvent suivre certaines fonctionnalités de la classe parent (classe héréditaire). Bien sûr, les sous-classes peuvent également avoir leurs propres propriétés et opérations indépendantes
L'héritage est une forme de réutilisation logicielle. De nouvelles classes sont générées par des classes existantes, et de nouveaux attributs et comportements sont ajoutés en conservant leurs propriétés et leurs comportements, et en modifiant les performances en fonction des exigences de la nouvelle classe. Si une classe d'enfants n'hérite qu'à partir d'une classe parent, elle est appelée héritage unique; Si une classe d'enfants hérite de plus d'une classe parent, elle s'appelle multi-inheritance. Notez que Java ne prend pas en charge l'héritage multiple, mais il prend en charge le concept d '"interface". Les interfaces permettent à Java d'obtenir de nombreux avantages de l'héritage multiple et d'abandonner les inconvénients correspondants. Remarque: C ++ prend en charge plusieurs héritage
Définition de la relation d'héritage:
[Modificateur] Le nom de la sous-classe de classe étend le nom de la classe parent, nom de classe parent 2
Le nom de la classe parent suit
Le mot-clé est utilisé pour indiquer quelle sous-classe de la classe actuelle est déjà là, et il existe une relation d'héritage.
Définissez deux sous-classes de l'employé de la classe des employés:
Catégorie des employés généraux: CommonEmployee
Catégorie de superviseur: ManagerEmployee
Il y a deux aspects principaux de l'héritage des sous-classes de la classe parent:
(1) Héritage des attributs. Par exemple, une entreprise est une classe de parents et une entreprise a un nom, une adresse, un gestionnaire, un employé, etc., qui sont tous des aspects structurels.
(2) Héritage de la méthode. Une classe de parents définit plusieurs opérations, comme une entreprise qui doit avoir des projets, des bénéfices, une nomination de gestionnaires, recruter des employés, etc., et la filiale héritera également de ces actions S; MP
ClassComMonEmployeeExtend Employee // Sous-Class 1: {intm_managerno; // Define Class Attribut M_ManagerNo, représentant le numéro de boss de l'employé} classManageRestEeEExtend Employee // Subclass 2: {Intm_SecretaryNo; // Define Class Attribut M_Secretor Attribuer l'héritage et se cacher
Bien que la classe des employés soit une classe de parents, cela ne signifie pas qu'il a plus de fonctions simplement parce qu'il s'agit d'une classe parent. Au contraire, les sous-analogues ont plus de fonctions que leurs classes de parents. Étant donné que la sous-classe est une extension de la classe parent, les attributs et les méthodes que la classe parent n'ont pas sont ajoutés (1) La sous-classe ne peut pas accéder au membre privé de la classe parent, mais la sous-classe peut accéder au public de sa classe parent.
(2) L'accès protégé est un niveau intermédiaire protecteur entre l'accès public et privé.
(3) Étant donné que les membres hérités de la classe des parents ne sont pas répertoriés dans la déclaration de sous-classe, ces membres existent dans la sous-classe.
Ici, nous devons faire la distinction entre l'héritage, l'écrasement et la surcharge, plusieurs concepts déroutants:
Ce n'est qu'au niveau conceptuel de la méthode que ces trois concepts peuvent être facilement confus:
Héritage de la méthode
Pour les objets de sous-classe, les méthodes de la classe parent peuvent être utilisées. Même si ces méthodes ne sont pas clairement définies dans la sous-classe, elles sont automatiquement héritées de la classe parent.
Couverture de la méthode
Méthode La remplacement fait référence à: Une méthode qui définit une méthode avec le même nom pour écraser la classe parent, qui est une implémentation de la technologie polymorphe. Lorsque la méthode de la classe parent est écrasée dans la classe enfant, c'est généralement la version de classe enfant qui appelle la version de la classe parent et fait un travail supplémentaire.
Il y a beaucoup de choses à noter. Ici, je mentionne principalement ceci et super. Il y a cela en C ++ (et le concept est similaire à celui de Java), mais il n'y a pas de super.
Cela représente l'objet actuel lui-même, et cela représente une référence à l'objet actuel. Il peut être compris comme un autre nom de l'objet. Cela vous permet d'appeler les méthodes et les propriétés de l'objet actuel.
Par exemple: this.getName () et getName () sont les mêmes dans la classe.
Super représente l'objet de classe parent directe de l'objet actuel et est la surcharge de la méthode de référence de l'objet de classe parent de l'objet actuel.
Définition de la surcharge: La méthode peut être définie avec le même nom de méthode mais différentes tables de paramètres (le nombre, le type ou l'ordre des paramètres dans la table de paramètres a des valeurs différentes), qui est appelée surcharge de méthode.
• Surcharge: la surcharge se produit lorsque plusieurs méthodes ont le même nom et contiennent différents paramètres. Le compilateur doit choisir la méthode à appeler. Il choisit la méthode correcte en comparant les types de paramètres dans différents en-têtes de méthode avec les types de valeurs utilisées dans des appels de méthode spécifiques.
Le polymorphisme permet le traitement des variables existantes et des classes connexes dans un style unifié, ce qui facilite l'ajout de nouvelles fonctionnalités dans le système. Ici, la publication des informations que vous avez trouvées en ligne peut plus clairement clarifier les polymorphismes et les problèmes de succession qui nécessitent une attention particulière dans l'héritage:
Polymorphismes de java
La programmation orientée objet a trois caractéristiques, à savoir l'encapsulation, l'héritage et le polymorphisme.
L'encapsulation masque le mécanisme de mise en œuvre interne de la classe, afin que la structure interne de la classe puisse être modifiée sans affecter l'utilisateur, tout en protégeant les données.
L'héritage consiste à réutiliser le code de classe parent lors de la préparation de la mise en œuvre du polymorphisme. Alors, qu'est-ce que le polymorphisme?
La réécriture, la surcharge et la connexion dynamique constituent le polymorphisme. L'une des raisons pour lesquelles Java a introduit le concept de polymorphisme est qu'il est différent de C ++ en termes d'hérédité de classe. Ce dernier permet un héritage multiple, ce qui lui apporte des fonctions très puissantes, mais la relation d'héritage complexe apporte également plus de problèmes aux développeurs C ++. Afin d'éviter les risques, Java n'autorise que l'héritage unique, et il existe une relation IS-A entre les classes dérivées et les classes de base (c'est-à-dire que les "chats" sont un "animal"). Bien que cela garantit la simplicité et la clarté de la relation de succession, elle aura inévitablement de grandes limitations fonctionnelles. Par conséquent, Java a présenté le concept de polymorphisme pour compenser cette lacune. De plus, les classes abstraites et les interfaces sont également des moyens importants pour résoudre les limites des réglementations sur l'héritage unique. Dans le même temps, le polymorphisme est également l'essence de la programmation orientée objet.
Pour comprendre le polymorphisme, vous devez d'abord savoir ce qu'est la "transformation ascendante".
J'ai défini un chat sous-classe, qui hérite de la classe animale, et le second est que le premier est la classe parentale. Je peux passer
Cat C = new Cat ();
Instanciation d'un objet CAT n'est pas difficile à comprendre. Mais quand je le définis comme ceci:
Animal a = new cat ();
Qu'est-ce que cela signifie?
C'est simple, cela signifie que je définis une référence de type animal à un objet nouvellement créé de type chat. Étant donné que le chat est hérité de son animal de classe parent, une référence à un type d'animal peut pointer vers un objet de type CAT. Alors, quel est l'intérêt de faire ça? Étant donné que les sous-classes sont une amélioration et une extension de la classe parent, les sous-classes sont généralement plus puissantes que les classes parentales en fonction, et leurs attributs sont plus uniques que les classes parentales.
La définition d'une référence à un type de classe parent pointe vers un objet sous-classé peut non seulement utiliser les fonctions puissantes de la sous-classe, mais également extraire les points communs de la classe parent.
Par conséquent, une référence au type de classe parent peut appeler toutes les propriétés et méthodes définies dans la classe parent, et elle est impuissante pour les méthodes définies dans la classe enfant mais pas dans la classe parent;
Dans le même temps, une méthode dans la classe parent ne peut être appelée que par une référence au type de classe parent si elle est définie dans la classe parent mais non remplacée dans la classe enfant;
Pour les méthodes définies dans la classe parent, si la méthode est réécrite dans la classe enfant, la référence au type de classe parent appellera cette méthode dans la classe enfant, qui est une connexion dynamique.
Regardez le programme suivant:
classe Père {public void func1 () {func2 (); } // Ceci est la méthode func2 () dans la classe parent, car la méthode est remplacée dans la sous-classe ci-dessous // donc lorsqu'elle est appelée dans la référence du type de classe parent, cette méthode ne sera plus valide // remplacera la méthode func2 () remplacée dans la sous-classe publique void func2 () {System.out.println ("aaa"); }} classe Child étend le père {// func1 (int i) est une surcharge de la méthode func1 () // puisque cette méthode n'est pas définie dans la classe parent, elle ne peut pas être appelée par la référence du type de classe parent // donc dans la méthode principale ci-dessous Child.func1 (68) est mauvais public vide func1 (int i) {system.out.println ("bbb"); } // func2 () réécrit la méthode func2 () dans la classe parent père // Si la méthode func2 () est appelée dans la référence au type de classe parent, il doit être la méthode réécrite dans la sous-classe publique void func2 () {System.out.println ("ccc"); }} classe publique PolymorphismTest {public static void main (String [] args) {père enfant = new child (); child.func1 (); // quel sera le résultat de l'impression? }}Le programme ci-dessus est un exemple très typique de polymorphisme. L'enfant de la classe enfant hérite du père de la classe parent, surcharge la méthode Func1 () de la classe parent et écrase la méthode Func2 () de la classe parent. Les Func1 surchargés (int i) et func1 () ne sont plus la même méthode. Puisqu'il n'y a pas de func1 (int i) dans la classe parent, l'enfant de référence du type de classe parent ne peut pas appeler la méthode func1 (int i). Si la sous-classe remplace la méthode func2 (), alors l'enfant de référence du type de classe parent appellera le func2 () réécrit dans la sous-classe lors de l'appel de la méthode.
Alors, quels résultats le programme imprimera-t-il?
De toute évidence, ce devrait être "CCC".
Pour le polymorphisme, il peut être résumé comme:
(1) Utilisez des références du type de classe parent pour pointer vers l'objet de la sous-classe (objet réel);
(2) Cette référence ne peut appeler que des méthodes et des variables définies dans la classe parent;
(3) Si une méthode dans la classe parent est réécrite dans la sous-classe, alors lors de l'appel de cette méthode, la méthode dans la sous-classe sera appelée; (connexion dynamique, appel dynamique)
(4) Les variables ne peuvent pas être réécrites (remplacées). Le concept de «réécriture» est uniquement pour les méthodes. Si les variables de la classe parent sont "réécrivez" dans la sous-classe, une erreur sera signalée lors de la compilation.
Le polymorphisme est à travers:
(1) L'interface et implémenter l'interface et écraser plusieurs classes différentes qui couvrent la même méthode dans l'interface (2) la classe parent et la classe parent et la classe parent et écrasent plusieurs sous-classes différentes qui couvrent la même méthode dans la classe parent.
1. Concepts de base
Polymorphisme: envoyez un message à un objet et laissez l'objet décider à quel comportement répondre.
Les appels de méthode dynamique sont implémentés en attribuant des références d'objet sous-classe aux variables de référence d'objet Superclass.
Ce mécanisme d'AVA suit un principe: Lorsqu'un objet Superclass fait référence à une variable pour se référer à un objet de sous-classe, le type de l'objet référencé plutôt que le type de variable référencée détermine dont la méthode membre est appelée, mais la méthode appelée doit être définie dans la superclasse, c'est-à-dire la méthode couverte par la sous-classe.
(1) Si A est une référence à la classe A, alors A peut pointer vers une instance de classe A, ou vers une sous-classe de classe A.
(2) Si A est une référence à l'interface A, alors A Pointer vers une instance d'une classe qui implémente l'interface A.
Mécanisme de mise en œuvre du polymorphisme Java
Mécanisme de mise en œuvre actuel de Sun JVM, la référence d'une instance de classe est un pointeur vers une poignée, qui est une paire de pointeurs:
Un pointeur pointe vers un tableau, et en fait, ce tableau a également deux pointeurs (un pointeur pointe vers un tableau de méthode contenant l'objet, et l'autre pointeur vers un objet de classe, indiquant le type auquel appartient l'objet);
Un autre pointeur pointe vers un morceau d'espace mémoire alloué à partir du tas Java.
Résumer
(1) Les appels de méthode dynamique sont implémentés en attribuant des références d'objet sous-classe aux variables de référence d'objet Superclass.
Dérivéc c2 = new dérivéc (); Baseclass A1 = C2; // Classe de base BaseClass, DerivedC est a1.play () hérité de Baseclass; //play() is defined in BaseClass and DerivedC, that is, the subclass overrides the method
analyser:
* 为什么子类的类型的对象实例可以覆给超类引用?
自动实现向上转型。通过该语句,编译器自动将子类实例向上移动,成为通用类型BaseClass;
* un. Will play() execute a method defined by the subclass or a parent class?
子类的。在运行时期,将根据a这个对象引用实际的类型来获取对应的方法。所以才有多态性。一个基类的对象引用,被赋予不同的子类对象引用,执行该方法时,将表现出不同的行为。
在a1=c2的时候,仍然是存在两个句柄,a1和c2,但是a1和c2拥有同一块数据内存块和不同的函数表。
(2)不能把父类对象引用赋给子类对象引用变量
BaseClass a2=new BaseClass(); DerivedC c1=a2;//出错
在java里面,向上转型是自动进行的,但是向下转型却不是,需要我们自己定义强制进行。
c1=(DerivedC)a2; 进行强制转化,也就是向下转型.
(3)记住一个很简单又很复杂的规则,一个类型引用只能引用引用类型自身含有的方法和变量。
你可能说这个规则不对的,因为父类引用指向子类对象的时候,最后执行的是子类的方法的。
其实这并不矛盾,那是因为采用了后期绑定,动态运行的时候又根据型别去调用了子类的方法。而假若子类的这个方法在父类中并没有定义,则会出错。
例如,DerivedC类在继承BaseClass中定义的函数外,还增加了几个函数(例如myFun())
analyser:
当你使用父类引用指向子类的时候,其实jvm已经使用了编译器产生的类型信息调整转换了。
这里你可以这样理解,相当于把不是父类中含有的函数从虚拟函数表中设置为不可见的。注意有可能虚拟函数表中有些函数地址由于在子类中已经被改写了,所以对象虚拟函数表中虚拟函数项目地址已经被设置为子类中完成的方法体的地址了。
(4)Java与C++多态性的比较
jvm关于多态性支持解决方法是和c++中几乎一样的,
只是c++中编译器很多是把类型信息和虚拟函数信息都放在一个虚拟函数表中,但是利用某种技术来区别。
Java把类型信息和函数信息分开放。Java中在继承以后,子类会重新设置自己的虚拟函数表,这个虚拟函数表中的项目有由两部分组成。从父类继承的虚拟函数和子类自己的虚拟函数。
虚拟函数调用是经过虚拟函数表间接调用的,所以才得以实现多态的。
Java的所有函数,除了被声明为final的,都是用后期绑定。
1个行为,不同的对象,他们具体体现出来的方式不一样,
比如: 方法重载overloading 以及方法重写(覆盖)override
class Human{ void run(){输出人在跑} } class Man extends Human{ void run(){输出男人在跑} } 这个时候,同是跑,不同的对象,不一样(这个是方法覆盖的例子) class Test{ void out(String str){输出str} void out(int i){输出i} }这个例子是方法重载,方法名相同,参数表不同
ok,明白了这些还不够,还用人在跑举例
Human ahuman=new Man();
这样我等于实例化了一个Man的对象,并声明了一个Human的引用,让它去指向Man这个对象意思是说,把Man这个对象当Human看了.
比如去动物园,你看见了一个动物,不知道它是什么, "这是什么动物? " "这是大熊猫! "
这2句话,就是最好的证明,因为不知道它是大熊猫,但知道它的父类是动物,所以,
这个大熊猫对象,你把它当成其父类动物看,这样子合情合理.
这种方式下要注意new Man();的确实例化了Man对象,所以ahuman.run()这个方法输出的是"男人在跑"
如果在子类Man下你写了一些它独有的方法比如eat(),而Human没有这个方法,
在调用eat方法时,一定要注意强制类型转换((Man)ahuman).eat(),这样才可以...
对接口来说,情况是类似的...
Exemple:
package domain; //Define superA class superA { int i = 100; void fun(int j) { j = i; System.out.println("This is superA"); } } //Define superA subclass subB class subB extends superA { int m = 1; void fun(int aa) { System.out.println("This is subB"); } } //Define superA subC class subC extends superA { int n = 1; void fun(int cc) { System.out.println("This is subB"); } } //Define superA subC class subC extends superA { int n = 1; void fun(int cc) { System.out.println("This is subC"); } } class Test { public static void main(String[] args) { superA a = new superA(); subB b = new subB(); subC c = new subC(); a = b; a.fun(100); a = c; a.fun(200); }} /*
* 上述代码中subB和subC是超类superA的子类,我们在类Test中声明了3个引用变量a, b,
* c,通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用。也许有人会问:
* "为什么(1)和(2)不输出:This is superA"。
* java的这种机制遵循一个原则:当超类对象引用变量引用子类对象时,
* 被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,
* 但是这个被调用的方法必须是在超类中定义过的,
* 也就是说被子类覆盖的方法。
* 所以,不要被上例中(1)和(2)所迷惑,虽然写成a.fun(),但是由于(1)中的a被b赋值,
* 指向了子类subB的一个实例,因而(1)所调用的fun()实际上是子类subB的成员方法fun(),
* 它覆盖了超类superA的成员方法fun();同样(2)调用的是子类subC的成员方法fun()。
* 另外,如果子类继承的超类是一个抽象类,虽然抽象类不能通过new操作符实例化,
* 但是可以创建抽象类的对象引用指向子类对象,以实现运行时多态性。具体的实现方法同上例。
* 不过,抽象类的子类必须覆盖实现超类中的所有的抽象方法,
* 否则子类必须被abstract修饰符修饰,当然也就不能被实例化了
* /
以上大多数是以子类覆盖父类的方法实现多态.下面是另一种实现多态的方法-----------重写父类方法
JAVA里没有多继承,一个类之能有一个父类。而继承的表现就是多态。一个父类可以有多个子类,而在子类里可以重写父类的方法(例如方法print()),这样每个子类里重写的代码不一样,自然表现形式就不一样。这样用父类的变量去引用不同的子类,在调用这个相同的方法print()的时候得到的结果和表现形式就不一样了,这就是多态,相同的消息(也就是调用相同的方法)会有不同的结果。举例说明:
//Premary class public class Father{ //The parent class has a method to hit the child public void hitChild(){ } } //Subclass 1 public class Son1 extends Father{ //Rewrite the method to hit the child public void hitChild(){ System.out.println("Why hit me? What I did wrong!"); } } //Subclass 2 public class Son2 extends Father{ //Rewrite the method to hit the child public void hitChild(){ System.out.println("I know I'm wrong, stop hitting it!"); } } //Subclass 3 public class Son3 extends Father{ //Rewrite the parent class hits the child method public void hitChild(){ System.out.println("I run, you can't hit!"); } } //Test class public class Test{ public static void main(String args[]){ Father father; father = new Son1(); father.hitChild(); father = new Son2(); father.hitChild(); father = new Son3(); father.hitChild(); }}都调用了相同的方法,出现了不同的结果!这就是多态的表现!
import java.io.*;class Super{ Super(){ System.out.println("This is super class!"); } void method(){ System.out.println("Super's method"); }}class Sub extends Super{ Sub(){ super(); System.out.println("/n/t:and here is the child"); } void method(){ System.out.println("child's method"); }}public class Super_Sub{ public static void main(String[] args){ Super sup=new Sub(); sup.method(); Sub child=(Sub)new Super();//Here, the actual allocated memory is Super, but Child is used to refer to it. This is "downward transformation" (the parent class impersonates a child class, because the subclass is down when drawing in UML), and it must be casted by child.method(); }}对于数据来说,继承是否为正确的设计可以用一个简单的规则来判断。“is-a”规则表明子类的每一个对象都是一个超类的对象。例如,每一个经理是一个员工。然而,只有经理类是员工类的子类才是有意义的。很明显,反过来就不行了――并不是每个员工都是经理。
还有一个明确叙述“is-a”规则的方法是替代原则。该原则规定无论何时,如果程序需要一个超类对象,都可以用一个子类对象来代替
动态绑定
理解调用一个对象方法的机制是非常重要的。下面具体介绍:Xf;
(1)编译器检查对象的声明类型和方法名。
(2) Next, the compiler checks the parameter type in the method call. If one of all methods called f has a parameter type whose parameter type best matches the parameter type provided by the call, the method will be selected to call. This process is called overload selection. (statique)
(3)当程序运行并且使用动态绑定来调用一个方法时,那么虚拟机必须调用同x所指向的对象的实际类型相匹配的方法版本。
...
如果类中没有写构造函数,那么系统会自动为该类提供一个默认构造函数,该构造函数将所有的实例字段初始化为默认值:
...
包用途:
Java允许把多个类收集在一起成为一组,称作包(package)。包便于组织任务,以及使自己的任务和其他人提供的代码库相分离。
标准Java库被分类成许多的包,其中包括java.1ang、java.util和java.net等等。标准Java包是分层次的。就像在硬盘上嵌套有各级子目录一样,可以通过层次嵌套组织包。所有的Java包都在Java和Javax包层次内
创建包
已经看到,已有的库,比如JavaAPI中的类和接口,可以导入到Java程序中。
Java API中的每一个类和接口属于一个特定的包。它包含一组相关联的类和接口,实际是对类和接口进行组织的目录结构。
例如,假定文件名是MyClass.java。它意味着在那个文件有一个、而且只能有一个public类。而且那个类的名字必须是MyClass(包括大小写形式):
packagemypackage;publicclass MyClass{……}创建可复用的类的步骤简要说明如下:
(1)定义一个public类。如果类不是public,它只能被同一包中的其他类使用。
(2)选择一个包名,并把package语句加到可复用的类的源代码文件中。
(3)编译这个类。这样,它就被放到适当的包目录结构中,以供编译器和解译器使用。
(4)把这个可复用的类导入到需要用它的程序中。现在就可以使用它了。
注意在Java语言中可以出现在类定义的括号外面的仅有两个语句,它们是package和import。
包引用---每个类名前加上完整的包名
例如,给出一个指向此包中的类的快捷方式。一旦使用import(导入)了以后,就不再需要给出完整的包名。
可以引入一个特定的类,也可以引入整个包。import语句要放在源文件的头部(但在所有package语句的下面)。例如,可以通过下面的语句引入在java.util包中的所有的类:
importjava.util.*;
然后,就可以使用
Datetoday=new Date();
而不需要在前面加上包名。也可以引入包中某个特定的类:
importjava.util.Date;
要把类放人一个包中,必须把此包的名字放在源文件头部,并且放在对包中的类进行定义的代码之前。例如,在文件Employee.java的开始部分如下:
packagecom.horstmann.corejava;publicclass Employee{……}把包中的文件放入与此完整的包名相匹配的子目录中。例如,在包com.horstmann.corejava中的所有的类文件都必须放在子目录com/horstmann/core.java(Windows下的com/horstmann/corejava)下。这是最简单的一种方法
类被存储在文件系统的子目录中。类的路径必须与所在包名相匹配。
在前面的例子中,包目录com/horstmann/corejava是程序目录的一个子目录。然而这样安排很不灵活。一般,有多个程序需要访问包文件。为了使包可以在多个程序间共享,需要做以下事情:
1)把类放在一个或多个特定的目录中,比如/home/user/classdir。此目录是包树的基本目录。如果加入了类com.horstmann.corejava.Employee,那么此类文件必须位于子目录/home/user/classdir/com/horstmann/corejava下。
2)设置类路径。类路径是其子目录包含类文件的所有基本目录的集合。classpath
已经接触过public和private访问指示符。
被标记为Public的部件可以被任何类使用,而私有部件只能被定义它们的类使用。如果没有指定public或private,那么部件(即类、方法或变量)可以被同一个包中的所有方法访问。
Java API包
为了简化面向对象的编程过程,Java系统事先设计并实现了一些体现了常用功能的标准类,如用于输入/输出的类,用于数学运算的类,用于图形用户界面设计的类,用于网络处理的类等。这些系统标准类根据实现的功能不同,可以划分成不同的集合,每个集合是一个包,合称为类库。可以引用这些包,也可以创建自己的包。
Java的类库是系统提供的已实现的标准类的集合,是Java编程的API,它可以帮助开发者方便、快捷地开发Java程序
接口主要作用是可以帮助实现类似于类的多重继承的功能。在Java中,出于简化程序结构的考虑,不再支持类间的多重继承而只支持单重继承,即一个类至多只能有一个直接父类。然而在解决实际问题的过程中,仅仅依靠单重继承在很多情况下都不能将问题的复杂性表述完整,需要其他的机制作为辅助。
接口声明
Java中声明接口的语法如下:
[public] interface 接口名[extends 父接口名列表]{ //接口体;//常量域声明[public] [static] [final] 域类型域名=常量值; //抽象方法声明[public] [abstract] 返回值方法名(参数列表) [throw异常列表];}从上面的语法规定可以看出,定义接口与定义类非常相似,实际上完全可以把接口理解成为一种特殊的类,接口是由常量和抽象方法组成的特殊类
(1)接口中的属性都是用final修饰的常量,
(2)接口中的方法都是用abstract修饰的抽象方法,在接口中只能给出这些抽象方法的方法名、返回值和参数列表,而不能定义方法体,即仅仅规定了一组信息交换、传输和处理的“接口”
接口的实现
一个类要实现某个或某几个接口时,有如下的步骤和注意事项:
(1)在类的声明部分,用implements关键字声明该类将要实现哪些接口;
comme suit:
class类名implements接口{ }(2)如果实现某接口的类不是abstract的抽象类,则在类的定义部分必须实现指定接口的所有抽象方法,即为所有抽象方法定义方法体,而且方法头部分应该与接口中的定义完全一致,即有完全相同的返回值和参数列表;
(3)如果实现某接口的类是abstract的抽象类,则它可以不实现该接口所有的方法。
(4)一个类在实现某接口的抽象方法时,必须使用完全相同的方法头。
(5)接口的抽象方法,其访问限制符都已指定是public,所以类在实现方法时,必须显式地使用public修饰符。
résumé:
多重继承是指一个子类继承多个父类。Java不支持多重继承,但Java提供了接口。
子类不能访问父类的private成员,但子类可以访问其父类的public,protected和包访问成员;要访问父类的包访问成员,子类一定要在父类的包内。
子类构造函数总是先调用(显式的或隐式地)其父类的构造函数,以创建和初始化子类的父类成员。
子类的对象可以当作其父类的对象对待,反之则不行(即向上转型)
protected访问是public和private访问之间一个保护性的中间层次。父类方法、子类方法和在同一个包内类的方法都能访问父类的protected成员,但其他方法均不能访问
一个子类对象引用可以隐式地转换成一个父类对象引用。使用显式的类型转换,可以把父类引用转换成子类引用。如果目标不是子类对象,将产生ClassCastException例外处理。