protégé
Parlons des questions de droits d'accès protégées. Voir l'exemple 1 ci-dessous:
Test.java
class myObject {} public class test {public static void main (String [] args) {myObject obj = new myObject (); obj.clone (); // compiler l'erreur. }} Le clone de méthode de l'objet type n'est pas visible.
Nous avons déjà compris que Object.Clone () est une méthode protégée. Cela montre que la méthode est accessible par des sous-classes du même package (java.lang) et IT (java.lang.object). Voici la classe MyObject (l'héritage par défaut de java.lang.object).
De même, le test est également une sous-classe de java.lang.object. Cependant, la méthode protégée d'une autre sous-classe ne peut pas être accessible dans une sous-classe, bien que les deux sous-classes héritent de la même classe parent.
Regardons à nouveau l'exemple 2:
Test2.java
classe myObject2 {objet protégé clone () lève ClonenotsupportEdException {return super.clone (); }} classe publique Test2 {public static void main (String [] args) lève ClonenotsupporTedException {myObject2 obj = new myObject2 (); obj.clone (); // compiler ok. }} Ici, nous employons la méthode Clone () de la classe parent dans la classe MyObject2, appelons la méthode clone () dans une autre classe Test2 et compile et passez.
La raison de la compilation est évidente. Lorsque vous remplacez la méthode Clone () dans la classe MyObject2, la classe MyObject2 et la classe Test2 sont sous le même package, donc cette méthode protégée est visible pour la classe Test2.
À ce stade, nous rappelons les déclarations du chapitre 2.2 dans les articles de copie superficielle et profonde en Java, écrasent la méthode clone () de la classe de base dans la classe dérivée et la déclarez comme publique. Maintenant, je comprends la raison de cette phrase (afin de permettre à d'autres classes d'appeler la méthode clone () de cette classe, après la surcharge, l'attribut de la méthode clone () doit être défini en public).
Jetons un coup d'œil à l'exemple 3:
Test3.java
Package 1Class myObject3 {Protected Object Clone () lève ClonenotsupportEdException {return super.clone (); }} package 2Public class test3 étend myObject3 {public static void main (String args []) {myObject3 obj = new myObject3 (); obj.clone (); // compiler l'erreur. TEST3 TOBJ = nouveau test3 (); tobj.clone (); // complie ok. }} Ici, j'utilise la classe Test3 pour hériter de MyObject3. Notez que ces deux classes ont des packages différents, sinon c'est le cas de l'exemple 2. Dans la classe Test3, appelez la méthode Clone () de l'instance TOBJ de la classe Test3 et compile et passe. Et également appeler la méthode clone () de l'instance obj de la classe myObject3 est appelée, et l'erreur de compilation!
Résultats inattendus, la méthode protégée ne peut-elle pas être accessible par des classes héritées?
Il doit être clair que la classe Test3 hérite de la classe MyObject3 (y compris sa méthode de clone), vous pouvez donc appeler votre propre méthode de clone dans la classe test3. Cependant, la méthode protégée de la classe MyObject3 est invisible à ses différents tests de sous-classe BUN3.
Voici un autre passage de "Java in a Nutshell":
L'accès protégé nécessite un peu plus de laboratoire. Supposons que la classe A déclare un champ protégé X et est étendu par une classe B, qui est définie dans un ensemble différent (ce dernier point est important). La classe B hérite du champ protégé X, et son code peut accéder à ce champ dans l'instance actuelle de B ou dans tout autre cas de B auquel le code peut se référer. Cela ne signifie cependant pas que le code de classe B peut commencer à lire les champs protégés des instances arbitraires de A! Si un objet est une instance de A mais n'est pas une instance de B, ses champs ne sont évidemment pas hérités par B et le code de classe B ne peut pas les lire.
Soit dit en passant, de nombreux livres Java en Chine sont généralement décrits de cette manière lors de l'introduction d'autorisations d'accès (diverses formes et contenu cohérent):
Contrôle d'accès de la méthode:
statique
1. MOT-CLÉ STATIQUE (N'oubliez pas ces premiers, puis lisez-le)
1) Les méthodes statiques et les variables statiques sont des objets qui appartiennent à une certaine classe, mais pas à une classe.
2) Les références aux méthodes statiques et aux variables statiques sont directement référencées via les noms de classe.
3) Les méthodes non statiques et les variables des membres non statiques ne peuvent pas être appelées dans des méthodes statiques. Sinon, c'est ok.
4) Les variables statiques sont similaires aux variables globales dans d'autres langues dans un programme et sont accessibles en dehors de la classe si elles ne sont pas privées.
2. Quand utiliser statique
Lorsque nous créons une instance d'une classe (objet), nous utilisons généralement la nouvelle méthode afin que l'espace de données de cette classe soit créé et que ses méthodes puissent être appelées.
Cependant, nous espérons parfois que bien qu'une classe puisse être créée avec N objets (évidemment, l'espace de données de ces n objets est différent), certaines des données de ces n objets sont les mêmes, c'est-à-dire, quel que soit le nombre d'instances de la classe, les données ont une copie de mémoire de ces instances (voir l'exemple 1). C'est le cas avec des variables statiques.
Un autre scénario est que vous voulez qu'une méthode ne soit associée à aucun objet de la classe qui le contient. C'est-à-dire que cette méthode peut être appelée même si l'objet n'est pas créé. Une utilisation importante de la méthode statique consiste à l'appeler sans créer d'objet (voir l'exemple 2). C'est le cas avec une méthode statique.
Il y a aussi une utilisation spéciale dans les classes intérieures. Habituellement, une classe normale n'est pas autorisée à être déclarée statique, seule une classe intérieure peut le faire. À l'heure actuelle, cette classe intérieure déclarée statique peut être utilisée directement comme classe normale sans avoir à installer une classe extérieure (voir l'exemple 3). C'est le cas avec les classes statiques.
Exemple 1
classe publique tStatic {static int i; public tStatic () {i = 4; } public tStatic (int j) {i = j; } public static void main (String args []) {System.out.println (tStatic.i); TStatic t = new tstatic (5); // Déclarez la référence de l'objet et instanciez-la. À ce moment, i = 5 System.out.println (Ti); TStatic tt = new tStatic (); // Déclarez la référence de l'objet et instanciez-la. À ce moment, i = 4 System.out.println (Ti); System.out.println (tt.i); System.out.println (Ti); }}
résultat:
05444
La variable statique est créée lorsque la classe est chargée. Tant que la classe existe, la variable statique existe. Ils doivent être initialisés lorsqu'ils sont définis. Dans l'exemple ci-dessus, I n'est pas initialisé, donc la valeur initiale par défaut 0 sera obtenue. La variable statique ne peut être initialisée qu'une seule fois, et la variable statique n'accepte que la dernière initialisation.
En fait, il s'agit toujours d'un problème avec plusieurs instances partageant une variable statique.
Exemple 2
Non déclaré comme statique
classa classa {int b; public void ex1 () {} classe classb {void ex2 () {int i; Classa a = new Classa (); i = ab; // Ici, accès à la variable membre B A.Ex1 () via la référence d'objet; // Ici Accès à la fonction membre Ex1 via la référence d'objet}}}
Déclaré comme statique
classa classa {static int b; static void ex1 () {}} classe classb {void ex2 () {int i; i = classa.b; // Ici Accès à la variable membre B classa.ex1 () via le nom de classe; // Ici Accès à la fonction membre Ex1 via le nom de classe}} Lorsque vous utilisez des méthodes statiques, veillez à ce que les méthodes non statiques ne puissent pas être appelées dans des méthodes statiques et référennent les variables des membres non statiques (ceci ou Super ne peut en aucun cas être référencé dans les méthodes statiques). La raison est très simple. Pour les choses statiques, lorsque le JVM charge la classe, il ouvre ces espaces statiques en mémoire (il peut donc être directement référencé via le nom de la classe), et à l'heure actuelle, la classe où les méthodes non statiques et les variables membre sont situées n'ont pas été instanciées.
Donc, si vous souhaitez utiliser des méthodes non statiques et des variables membre, vous pouvez instancier directement la classe où la méthode ou la variable membre se trouve dans la méthode statique. C'est ainsi que le public static Void Main le fait.
Exemple 3
classe publique staticcls {public static void main (string [] args) {outercls.innercls oi = new outercls.innercls (); // il n'est pas nécessaire de new outercls avant ce}} classe externct. }}}
résultat:
Interne
3. Initialisation statique
Les variables définies par statique auront la priorité sur toutes les autres variables non statiques, quel que soit l'ordre dans lequel ils apparaissent. Un bloc de code statique (suivi d'un morceau de code) est utilisé pour effectuer une initialisation de variable statique explicite. Ce code ne sera initialisé qu'une seule fois et lorsque la classe sera chargée pour la première fois. Voir l'exemple ci-dessous.
classe de classe {statique int c = 0; Valeur () {c = 15; } Valeur (int i) {c = i; } static void inc () {c ++; }} classe Count {public static void prt (String s) {System.out.println (s); } Valeur v = nouvelle valeur (10); Valeur statique v1, v2; statique {prt ("dans le bloc statique du nombre de cals v1.c =" + v1.c + "v2.c =" + v2.c); v1 = nouvelle valeur (27); prt ("dans le bloc statique du nombre de cals v1.c =" + v1.c + "v2.c =" + v2.c); v2 = nouveau valeur (); prt ("dans le bloc statique du nombre de cals v1.c =" + v1.c + "v2.c =" + v2.c); }} classe publique tStaticBlock {public static void main (String [] args) {count ct = new Count (); Count.prt ("dans le principal:"); Count.prt ("ct.c =" + ct.vc); Count.prt ("v1.c =" + count.v1.c + "v2.c =" + count.v2.c); Count.v1.inc (); Count.prt ("v1.c =" + count.v1.c + "v2.c =" + count.v2.c); Count.prt ("ct.c =" + ct.vc); }}
résultat:
Dans le bloc statique du nombre de CALSS V1.C = 0 V2.C = 0 dans le bloc statique du nombre de CALSS V1.C = 27 V2.C = 27 Dans le bloc statique du nombre de CALSS V1.C = 15 V2.C = 15 dans le principal: CT.C = 10V1.C = 10 V2.C = 10V1.C = 11 V2.C = 11CT.C = 11
Qu'il s'agisse de V, V1 ou V2, les variables membres sur lesquelles ils fonctionnent sont la même variable statique c.
Dans le nombre de classes, v1 et v2 (valeur statique v1, v2;), puis initialiser le bloc de code statique (statique {}), et enfin initialiser v.