protégé
Parlons des droits d'accès protégés. Regardez l'exemple 1 ci-dessous :
Test.java
class MyObject {} public class Test { public static void main(String[] args) { MyObject obj = new MyObject(); obj.clone(); // Compile error. } }
L'erreur mentionnée ci-dessus apparaît : La méthode clone du type Object n'est pas visible.
Nous le savons déjà que Object.clone() est une méthode protégée. Cela montre que cette méthode est accessible par les sous-classes sous le même package (java.lang) et par celle-ci (java.lang.Object). Voici la classe MyObject (qui hérite de java.lang.Object par défaut).
De même, Test est également une sous-classe de java.lang.Object. Cependant, les méthodes protégées d’une sous-classe ne sont pas accessibles depuis une autre sous-classe, même si les deux sous-classes héritent de la même classe parent.
Regardez à nouveau l'exemple 2 :
Test2.java
class MyObject2 { protected Object clone() throws CloneNotSupportedException { return super.clone(); } } public class Test2 { public static void main(String[] args) throws CloneNotSupportedException { MyObject2 obj = new MyObject2(); obj.clone(); // Compile OK. } }
Ici, nous remplaçons la méthode clone() de la classe parent dans la classe MyObject2, et dans une autre La méthode clone() est appelée dans une classe Test2 et la compilation réussit.
La raison pour laquelle la compilation réussit 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 par la classe Test2.
À ce stade de l'analyse, nous rappelons la déclaration du chapitre 2.2 de l'article sur la copie superficielle et la copie profonde en Java. ② Remplacez la méthode clone() de la classe de base dans la classe dérivée et déclarez-la comme publique. Vous comprenez maintenant la raison de cette phrase (afin de permettre à d'autres classes d'appeler la méthode clone() de cette classe, les propriétés de la méthode clone() doivent être définies sur public après surcharge).
Regardons l'exemple 3 :
Test3.java
package 1 class MyObject3 { protected Object clone() throws CloneNotSupportedException { return super.clone(); } } package 2 public class Test3 extends MyObject3 { public static void main(String args[]) { MyObject3 obj = new MyObject3(); obj.clone(); // Compile error. Test3 tobj = new Test3(); tobj.clone();// Complie OK. } }
Ici, j'utilise la classe Test3 pour hériter de MyObject3. Notez que ces deux-là. les classes sont des packages différents, sinon c'est la situation de l'exemple 2. Dans la classe Test3, la méthode clone() de l'instance tobj de la classe Test3 est appelée et la compilation réussit. Lorsque la méthode clone() de l'instance obj de la classe MyObject3 est également appelée, une erreur de compilation se produit !
Résultat inattendu, les méthodes protégées ne sont-elles pas accessibles aux classes héritées ?
Il doit être clair que la classe Test3 hérite de la classe MyObject3 (y compris sa méthode de clonage), vous pouvez donc appeler votre propre méthode de clonage dans la classe Test3. Mais la méthode protégée de la classe MyObject3 est invisible pour ses différentes sous-classes Test3.
Méthode de contrôle d'accès :
statique
1. Mot clé static (rappelez-vous-en d'abord, puis continuez à lire)
1) Les méthodes statiques et les variables statiques appartiennent à une certaine classe, pas aux objets de la classe.
2) Les références aux méthodes statiques et aux variables statiques sont directement référencées via le nom de la classe.
3) Les méthodes non statiques et les variables membres non statiques ne peuvent pas être appelées dans les méthodes statiques. Au contraire, ça va.
4) Les variables statiques sont similaires aux variables globales dans d'autres langages dans un certain programme. Si elles ne sont pas privées, elles sont accessibles en dehors de la classe.
2. Quand utiliser static
Lorsque nous créons une instance (objet) d'une classe, nous utilisons généralement la nouvelle méthode afin que l'espace de données de cette classe puisse être créé et ses méthodes puissent être appelées.
Cependant, nous espérons parfois que même si une classe peut créer n objets (évidemment les espaces de données de ces n objets sont différents), certaines données de ces n objets sont les mêmes, c'est-à-dire quelle que soit la classe. Combien d'instances sont là pour lequel il existe une copie mémoire de ces données (voir exemple 1). C'est le cas des variables statiques.
Une autre situation est celle où vous souhaitez qu'une méthode ne soit associée à aucun objet de la classe qui la contient. En d’autres termes, cette méthode peut être appelée même si l’objet n’est pas créé. Une utilisation importante des méthodes statiques est qu'elles peuvent être appelées sans créer d'objets (voir exemple 2). C'est le cas des méthodes statiques.
Il existe également un usage spécial qui se produit dans les classes internes. Habituellement, une classe ordinaire n'est pas autorisée à être déclarée statique, seule une classe interne le peut. À ce stade, la classe interne déclarée comme statique peut être utilisée directement comme classe normale sans instancier de classe externe (voir exemple 3). C'est le cas des classes statiques.
Exemple 1
public class 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); // 声明对象引用,并实例化。此时i=5 System.out.println(t.i); TStatic tt = new TStatic(); // 声明对象引用,并实例化。此时i=4 System.out.println(t.i); System.out.println(tt.i); System.out.println(t.i); } }
Résultat :
0 5 4 4 4
des variables statiques sont créées lorsque la classe est chargée et existeront tant que la classe existe. Ils doivent être initialisés une fois définis. Dans l'exemple ci-dessus, i n'est pas initialisé, donc la valeur initiale par défaut 0 sera obtenue. Les variables statiques ne peuvent être initialisées qu'une seule fois et les variables statiques ne reçoivent que la dernière initialisation.
En fait, il s'agit toujours d'un problème de plusieurs instances partageant une variable statique.
Exemple 2
Non déclaré comme statique
class ClassA { int b; public void ex1() {} class ClassB { void ex2() { int i; ClassA a = new ClassA(); i = a.b; // 这里通过对象引用访问成员变量b a.ex1(); // 这里通过对象引用访问成员函数ex1 } } }
Déclaré comme statique
class ClassA { static int b; static void ex1() {} } class ClassB { void ex2() { int i; i = ClassA.b; // 这里通过类名访问成员变量b ClassA.ex1(); // 这里通过类名访问成员函数ex1 } }
在使用静态方法时要注意,在静态方法中不能调用非静态的方法和引用非静态的成员变量(在static方法中也不能以任何方式引用this或super)。理由很简单,对于静态的东西,JVM在加载类时,就在内存中开辟了这些静态的空间(所以可以直接通过类名引用),而此时非静态的方法和成员变量所在的类还没有实例化。
所以如果要使用非静态的方法和成员变量,可以直接在静态方法中实例化该方法或成员变量所在的类。public static void main就是这么干的。
示例3
public class StaticCls { public static void main(String[] args) { OuterCls.InnerCls oi = new OuterCls.InnerCls();// 这之前不需要new一个OuterCls } } class OuterCls { public static class InnerCls { InnerCls() { System.out.println("InnerCls"); } } }
结果:
InnerCls
3.静态初始化
static定义的变量会优先于任何其它非static变量,不论其出现的顺序如何。静态代码块(在“static{”后面跟着一段代码),是用来进行显式的静态变量初始化,这段代码只会初始化一次,且在类被第一次装载时。看下面示例。
class Value { static int c = 0; Value() { c = 15; } Value(int i) { c = i; } static void inc() { c++; } } class Count { public static void prt(String s) { System.out.println(s); } Value v = new Value(10); static Value v1, v2; static { prt("in the static block of calss Count v1.c=" + v1.c + " v2.c=" + v2.c); v1 = new Value(27); prt("in the static block of calss Count v1.c=" + v1.c + " v2.c=" + v2.c); v2 = new Value(); prt("in the static block of calss Count v1.c=" + v1.c + " v2.c=" + v2.c); } } public class TStaticBlock { public static void main(String[] args) { Count ct = new Count(); Count.prt("in the main:"); Count.prt("ct.c=" + ct.v.c); 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.v.c); } }
结果:
in the static block of calss Count v1.c=0 v2.c=0 in the static block of calss Count v1.c=27 v2.c=27 in the static block of calss Count v1.c=15 v2.c=15 in the main: ct.c=10 v1.c=10 v2.c=10 v1.c=11 v2.c=11 ct.c=11
不管是v,v1还是v2,它们操作的成员变量都是同一个静态变量c。
在类Count中先初始化v1,v2(static Value v1, v2;),再初始化静态代码块(static{}),最后初始化v。
更多Explication détaillée des fonctions du modificateur protégé et du modificateur statique dans la programmation Java相关文章请关注PHP中文网!