geschützt
Sprechen wir über geschützte Probleme mit den Zugriffsrechten. Siehe Beispiel 1 unten:
Test.java
Klasse myObject {} public class Test {public static void main (String [] args) {myObject obj = new MyObject (); obj.clone (); // Fehler kompilieren. }} Der Methodenklon aus dem Typobjekt ist nicht sichtbar.
Wir haben bereits verstanden, dass Object.clone () eine geschützte Methode ist. Dies zeigt, dass auf die Methode durch Unterklassen desselben Pakets (Java.lang) und IT (Java.lang.Object) zugegriffen werden kann. Hier ist die MyObject -Klasse (die Standardvererbung von Java.lang.Object).
In ähnlicher Weise ist der Test auch eine Unterklasse von Java.lang.Object. Die geschützte Methode einer anderen Unterklasse kann jedoch nicht in einer Unterklasse zugegriffen werden, obwohl die beiden Unterklassen aus derselben übergeordneten Klasse erben.
Schauen wir uns Beispiel 2 erneut an:
Test2.java
class myObject2 {geschützte Objekt Clone () löscht ClonenotsuptedEdException {return Super.clone (); }} public class test2 {public static void main (String [] args) löscht Clonenotsupportedexception {myObject2 obj = new MyObject2 (); obj.clone (); // kompilieren ok. }} Hier überschreiben wir die Clone () -Methode der übergeordneten Klasse in der Klasse MyObject2, rufen die Clone () -Methode in einem anderen Klassen -Test2 auf und kompilieren und passieren.
Der Grund für die Zusammenstellung ist offensichtlich. Wenn Sie die Clone () -Methode in der MyObject2 -Klasse überschreiben, befinden sich die MyObject2 -Klasse und die TEST2 -Klasse unter demselben Paket, sodass diese geschützte Methode für die Test2 -Klasse sichtbar ist.
Zu diesem Zeitpunkt erinnern wir uns an die Aussagen in Kapitel 2.2 in den flachen und tiefen Kopierartikeln in Java, ② überschreiben Sie die Clone () -Methode der Basisklasse in der abgeleiteten Klasse und deklarieren sie als öffentlich. Jetzt verstehe ich den Grund für diesen Satz (um es anderen Klassen zu ermöglichen, die Clone () -Methode dieser Klasse aufzurufen, muss das Attribut der Clone () -Methode auf die Öffentlichkeit festgelegt werden).
Schauen wir uns Beispiel 3 an:
Test3.java
Paket 1Class MyObject3 {Protected Object Clone () löscht Clonenotsupportedexception {return Super.clone (); }} Paket 2Public class test3 erweitert myObject3 {public static void main (String args []) {myObject3 obj = new myObject3 (); obj.clone (); // Fehler kompilieren. Test3 tobj = new Test3 (); tobj.clone (); // complie ok. }} Hier verwende ich die Test3 -Klasse, um MyObject3 zu erben. Beachten Sie, dass diese beiden Klassen unterschiedliche Pakete haben. Andernfalls ist es der Fall von Beispiel 2. In der TEST3 -Klasse rufen Sie die Clone () -Methode des Instanztobj der Test3 -Klasse an und kompilieren und bestehen. Und auch die Clone () -Methode der Instanz obj der MyObject3 -Klasse und des Kompilierungsfehlers aufgerufen!
Unerwartete Ergebnisse, kann die geschützte Methode nicht von ererbten Klassen zugegriffen werden?
Es muss klar sein, dass die Klasse test3 MyObject3 (einschließlich seiner Klonmethode) erben, sodass Sie Ihre eigene Klonmethode in den Klassen Test3 aufrufen können. Die geschützte Methode der Klasse myObject3 ist jedoch für den verschiedenen Bun -Unterklassen -Test3 unsichtbar.
Hier ist eine weitere Passage von "Java auf den Punkt":
Der geschützte Zugang erfordert etwas mehr Arbeiter. Angenommen, die Klasse A deklariert ein geschütztes Feld X und wird durch eine Klasse B erweitert, die in einem anderen Paket definiert ist (dieser letzte Punkt ist wichtig). Klasse B erbt das geschützte Feld X, und sein Code kann auf dieses Feld in der aktuellen Instanz von B oder in anderen Fällen von B zugreifen, auf die sich der Code beziehen kann. Dies bedeutet jedoch nicht, dass der Code der Klasse B die geschützten Felder willkürlicher Instanzen von A! Wenn ein Objekt eine Instanz von A ist, aber keine Instanz von B ist, werden seine Felder offensichtlich nicht durch B geerbt, und der Code der Klasse B kann sie nicht lesen.
Übrigens werden viele Java -Bücher in China auf diese Weise auf diese Weise beschrieben, wenn die Zugriffsberechtigungen (verschiedene Formen und konsistente Inhalte) eingeführt werden:
Zugangskontrolle der Methode:
statisch
1. Keyword Static (Denken Sie zuerst an diese, dann lesen Sie es auf)
1) Statische Methoden und statische Variablen sind Objekte, die zu einer bestimmten Klasse gehören, jedoch nicht zu einer Klasse.
2) Verweise auf statische Methoden und statische Variablen werden direkt über Klassennamen referenziert.
3) Nichtstatische Methoden und nicht statische Mitgliedsvariablen können in statischen Methoden nicht aufgerufen werden. Ansonsten ist es in Ordnung.
4) Statische Variablen ähneln den globalen Variablen in anderen Sprachen in einem Programm und können außerhalb der Klasse zugegriffen werden, wenn sie nicht privat sind.
2. Wann zu statisch zu verwenden
Wenn wir eine Instanz einer Klasse (Objekt) erstellen, verwenden wir normalerweise die neue Methode, damit der Datenraum dieser Klasse erstellt und ihre Methoden aufgerufen werden können.
Manchmal hoffen wir jedoch, dass, obwohl eine Klasse mit N -Objekten erstellt werden kann (offensichtlich der Datenraum dieser N -Objekte unterschiedlich), einige der Daten dieser N -Objekte gleich sind, dh unabhängig davon, wie viele Fälle die Klasse hat, haben die Daten eine Speicherkopie dieser Instanzen (siehe Beispiel 1). Dies ist bei statischen Variablen der Fall.
Ein weiteres Szenario ist, dass Sie möchten, dass eine Methode keinem Objekt der Klasse zugeordnet ist, die sie enthält. Das heißt, diese Methode kann aufgerufen werden, auch wenn das Objekt nicht erstellt wird. Eine wichtige Verwendung der statischen Methode besteht darin, sie zu rufen, ohne ein Objekt zu erstellen (siehe Beispiel 2). Dies ist bei einer statischen Methode der Fall.
Es gibt auch eine besondere Verwendung in inneren Klassen. Normalerweise darf eine normale Klasse nicht als statisch erklärt werden, nur eine innere Klasse kann dies tun. Zu diesem Zeitpunkt kann diese innere Klasse, die als statisch deklariert wird, direkt als normale Klasse verwendet werden, ohne dass eine äußere Klasse eingesetzt werden musste (siehe Beispiel 3). Dies ist bei statischen Klassen der Fall.
Beispiel 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 = neuer Tstatic (5); // deklarieren Sie die Objektreferenz und instanziieren Sie sie. Zu diesem Zeitpunkt i = 5 system.out.println (ti); Tstatic tt = new Tstatic (); // deklarieren Sie die Objektreferenz und instanziieren Sie sie. Zu diesem Zeitpunkt i = 4 system.out.println (ti); System.out.println (tt.i); System.out.println (ti); }}
Ergebnis:
05444
Die statische Variable wird erstellt, wenn die Klasse geladen wird. Solange die Klasse existiert, existiert die statische Variable. Sie müssen bei definiert initialisiert werden. Im obigen Beispiel wird ich nicht initialisiert, sodass der Standard -Anfangswert 0 erhalten wird. Die statische Variable kann nur einmal initialisiert werden, und die statische Variable akzeptiert nur die letzte Initialisierung.
Tatsächlich ist dies immer noch ein Problem, wenn mehrere Instanzen eine statische Variable teilen.
Beispiel 2
Nicht als statisch deklariert
Klasse classa {int b; public void ex1 () {} class classB {void ex2 () {int i; Classa a = new classa (); i = ab; // hier Zugriff auf die Mitgliedsvariable b a.ex1 () durch Objektreferenz; // Hier zugreifen
Als statisch deklariert
Klasse classa {static int b; static void ex1 () {}} class classb {void ex2 () {int i; i = classa.b; // hier zugreift auf die Mitgliedsvariable b classa.ex1 () über den Klassennamen; // Hier zugreifen Achten Sie bei der Verwendung statischer Methoden darauf, dass nicht statische Methoden in statischen Methoden nicht aufgerufen werden und auf nicht statische Mitgliedsvariablen verweisen (auf diese oder Super in statischen Methoden kann nicht referenziert werden). Der Grund ist sehr einfach. Wenn die JVM die Klasse lädt, öffnet sie diese statischen Räume im Speicher (so kann sie direkt über den Klassennamen referenziert werden), und zu diesem Zeitpunkt wurde die Klasse, in der sich die nicht statischen Methoden und Mitgliedsvariablen befinden, nicht instanziiert.
Wenn Sie also nicht statische Methoden und Mitgliedsvariablen verwenden möchten, können Sie die Klasse direkt instanziieren, in der sich die Methode oder die Mitgliedervariable in der statischen Methode befindet. So macht es das öffentliche statische Leerraum.
Beispiel 3
public class staticcls {public static void main (String [] args) {outercls.innercls oi = new otercls.innercls (); // Es ist keine Notwendigkeit, vor diesem}} class outercls {public static class Innercls {Innercls () {System.out.Out.Out.Out.Out.Out.OUT.OUT.OUT.OUT.OUT.SPrintln ("Innercls"). }}}
Ergebnis:
Innercls
1. Statische Initialisierung
Die durch statischen Definition definierten Variablen haben vorrangig vor anderen nicht statischen Variablen, unabhängig von der Reihenfolge, in der sie erscheinen. Ein statischer Codeblock (gefolgt von einem Code) wird verwendet, um eine explizite statische Variableninitialisierung durchzuführen. Dieser Code wird nur einmal initialisiert und wenn die Klasse zum ersten Mal geladen wird. Siehe das Beispiel unten.
Klassenwert {static int c = 0; Value () {c = 15; } Value (int i) {c = i; } static void inc () {c ++; }} Klasse count {public static void prt (string s) {System.out.println (s); } Wert v = neuer Wert (10); statischer Wert V1, v2; static {prt ("im statischen Block von CALs zählen v1.c =" + v1.c + "v2.c =" + v2.c); v1 = neuer Wert (27); PRT ("Im statischen Block der CALs zählen v1.c =" + v1.c + "v2.c =" + v2.c); v2 = neuer Wert (); PRT ("Im statischen Block der CALs zählen v1.c =" + v1.c + "v2.c =" + v2.c); }} public class TstaticBlock {public static void main (String [] args) {count ct = new count (); Count.prt ("im Haupt:"); 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); }}
Ergebnis:
Im statischen Block von Calss zählen v1.c = 0 v2.c = 0in Der statische Block von Calss count v1.c = 27 v2.c = 27 im statischen Block von Calss Count v1.c = 15 v2.c = 15 in der Haupt: ct.c = 10v1.c = 10 v2.c = 10v1.c = 11 V2.C = 11CT.C = 11CT.C = 11CT.C = 11CT.C = 11CT = 11CT.C = 11CT.
Unabhängig davon, ob es sich um V, V1 oder V2 handelt, sind die Mitgliedervariablen, auf denen sie arbeiten, dieselbe statische Variable c.
In der Klassenanzahl initialisieren v1 und v2 (statischer Wert V1, v2;) den statischen Codeblock (statische {}) und initialisieren Sie schließlich v.