2012-05-23 13 views
31

Ich untersuche übergeordnete Elementfunktionen in JAVA und dachte über das Experimentieren mit übergeordneten Membervariablen nach.Überschreiben von Elementvariablen in Java

So I definiert Klassen

public class A{ 
    public int intVal = 1; 
    public void identifyClass() 
    { 
     System.out.println("I am class A"); 
    } 
} 

public class B extends A 
{ 
    public int intVal = 2; 
    public void identifyClass() 
    { 
     System.out.println("I am class B"); 
    } 
} 

public class mainClass 
{ 
    public static void main(String [] args) 
    { 
     A a = new A(); 
     B b = new B(); 
     A aRef; 
     aRef = a; 
     System.out.println(aRef.intVal); 
     aRef.identifyClass(); 
     aRef = b; 
     System.out.println(aRef.intVal); 
     aRef.identifyClass(); 
    } 
} 

Die Ausgabe lautet:

1 
I am class A 
1 
I am class B 

Ich bin nicht in der Lage zu verstehen, warum, wenn Aref gesetzt b INTVAL noch der Klasse A ist?

+0

mögliche Duplikat von [Geringfügige Verwirrung in Bezug auf das Überschreiben, wo Variablen betroffen sind] (http://stackoverflow.com/questions/12589274/slight-confusion-regarding-overriding-where-variables-are-concerned) –

+0

Ich denke Dies ist nicht die gleiche Frage, da der andere mehrere Merkmale der Sprache mischt, während dieser eine rein über Variablen ist, die nicht polymorph sind. –

+0

@Vic Seedoubleyew Aber es scheint mir wie ein Duplikat zu [dieser Frage] (http: // stackoverflow.com/q/7794621/1303323) –

Antwort

41

Variablen sind in Java nicht polymorph; sie übersteuern sich nicht.

+1

So, wie eine Variable nicht überschrieben wird, wird keine Laufzeitauflösung für sie ausgeführt, daher wird in der Vererbungskette der Variablenwert der Referenzklasse verwendet, wenn auf den Objekttyp zugegriffen wird . Ich habe es überprüft, indem ich die Klassen erweitert habe und einen Zwischenreferenztyp verwendet habe. Danke für die Antwort. –

45

Wenn Sie eine Variable mit dem gleichen Namen in einer Unterklasse erstellen, heißt das hiding. Die resultierende Unterklasse hat jetzt tatsächlich beide Eigenschaften. Sie können auf den von der Oberklasse mit super.var oder ((SuperClass)this).var zugreifen. Die Variablen müssen nicht einmal vom selben Typ sein; Sie sind nur zwei Variablen, die sich einen Namen teilen, ähnlich wie zwei überladene Methoden.

+0

Danke für die Antwort. –

+0

Also, solche Dinge zu tun, ist sowieso kein Polymorphismus. Veranschaulicht es das "Data-Hiding" -Konzept von OOPs? –

+0

@RahulRastogi Nein, es hat nichts mit diesem Konzept zu tun. "Data Hiding" ist die Kapselung. –

8

Variablen sind Compile-Zeit, Methoden Laufzeit aufgelöst. Das aRef ist vom Typ A, daher ist aRef.Intvalue auf 1 auf Kompilierungszeit aufgelöst.

+0

Danke für die Antwort –

0

Gemäß den Java-Spezifikationen werden die Instanzvariablen nicht von einer Unterklasse durch eine Unterklasse überschrieben, wenn sie erweitert wird.

Daher kann die Variable in der Unterklasse nur als eine mit dem gleichen Namen angesehen werden.

Auch wenn der Konstruktor von A während der Instanzerstellung von B aufgerufen wird, wird die Variable (intVal) initialisiert und damit die Ausgabe.

+0

Ich habe den ersten Punkt nicht bekommen. Wir können immer auf nicht private Membervariablen einer Superklasse in einer Unterklasse zugreifen. –

0

Nun, ich hoffe, du hast die Antwort. Wenn nicht, können Sie versuchen, im Debug-Modus zu sehen. Die Unterklasse B hat Zugriff auf beide intVal. Sie sind nicht polymorph und werden daher nicht überschrieben.

Wenn Sie die Referenz von B verwenden, erhalten Sie Bs intVal. Wenn Sie die Referenz von A verwenden, erhalten Sie A intVal. So einfach ist das.

+0

Im Debug-Modus sehe ich, dass sowohl b als auch aRef beide intVal s haben, während ich gemäß deinem Kommentar erwartet habe, dass nur Objekt b beide Werte haben wird. Liegt es daran, dass sich der Debugger anders verhält als die JVM? –

+0

Ich denke, es gab ein Missverständnis. Bis zu der Zeit, als du aRef nicht b zugewiesen hast, hatte es nur einen intVal.Wenn Sie b einem aRef zugewiesen haben, zeigt es jetzt auf ein Objekt vom Typ B, also zwei intVals. – dharam

+0

Danke für die Antwort –

-1

Java hat eine Feder der Kapselung bedeutet, dass es die Eigenschaft und das Verhalten eines Objekts fest bindet. also nur über eine Klassenreferenz können wir ihr Verhalten nennen, um ihre Eigenschaft zu ändern.

und in Vererbungsmethode überschreibt, so dass es nur seine Eigenschaft betrifft.

2

Von JLS Java SE 7 Ausgabe §15.11.1:

Dieser Mangel an dynamischen Lookup für Feldzugriffe ermöglicht Programme effizient mit einfachen Implementierungen ausgeführt werden. Die Möglichkeit des späten Bindens und Überschreibens ist verfügbar, jedoch nur, wenn Instanzmethoden verwendet werden.

Antworten von Oliver Charlesworth und Marko Topolnik korrekt sind, würde ich ein wenig mehr auf die erarbeiten gerne warum Teil der Frage:

In Java class members werden zugegriffen nach der Art der die Referenz und nicht die Art des tatsächlichen Objekts.Aus dem gleichen Grund, wenn Sie eine someOtherMethodInB() in Klasse B hätten, könnten Sie nicht auf aRef zugreifen, nachdem aRef = b ausgeführt wird. Bezeichner (dh Klassen-, Variablen-, usw. Namen) werden zur Kompilierzeit aufgelöst und der Compiler verlässt sich daher auf den Referenztyp.

Jetzt in Ihrem Beispiel, wenn System.out.println(aRef.intVal); läuft, druckt es den Wert intVal in A definiert, da dies der Typ der Referenz ist, die Sie verwenden, um darauf zuzugreifen. Der Compiler sieht, dass aRef vom Typ A ist und das ist der intVal, auf den zugegriffen wird. Vergessen Sie nicht, dass Sie beide Felder in den Instanzen von B haben. JLS hat auch ein ähnliches Beispiel wie Sie, "15.11.1-1. Statische Bindung für den Feldzugriff", wenn Sie einen Blick darauf werfen wollen.

Aber warum verhalten sich Methoden anders? Die Antwort ist, dass Java für Methoden späte Bindung verwendet. Das bedeutet, dass zur Kompilierungszeit die zur am besten geeignete Methode zur Laufzeit gefunden wird. Die Suche beinhaltet den Fall, dass die Methode in einer Klasse überschrieben wird.

3

Es gibt keinen Polymorphismus für Felder in Java.

Variables Entscheidung geschieht bei einer Kompilierung so immer Base Class Variablen (keine Kinder geerbt Variablen) zugegriffen wird.

Also, wenn Upcasting passiert, immer daran denken,

1) Basisklassenvariablen zugegriffen wird.

2) Unter Klassenmethoden (überschriebene Methoden beim Überschreiben passierte andere geerbte Methoden als von übergeordneten) wird aufgerufen.

0
OverRiding Concept in Java 
Functions will override depends on object type and variables will accessed on reference type. 

1. Override Function: In this case suppose a parent and child class both have same name of function with own definition. But which function will execute it depends on object type not on reference type on run time. 

For e.g.: 
Parent parent=new Child(); 
parent.behaviour(); 
//in that case parent is a reference of Parent class but holds the object of Child Class so thats why Parent class function will call in that case. 

Child child=new Child(); 
child.behaviour(); 
//in that case child holds the object of Child Class so thats why Child class function will call in that case. 

Parent parent=new Parent(); 
parent.behaviour(); 
//in that case parent holds the object of Parent Class so thats why Parent class function will call in that case. 

2. Override Variable: Java supports overloaded variables. But actually these are two different variables with same name. One in parent class ad second in child class. And both variable can be either of same datatype or different. 

When you trying to access the variable, it depends on reference type object not depends on object type. 

For e.g.: 
Parent parent=new Child(); 
System.out.println(parent.state); 

//in that case reference type is Parent so Parent class variable is accessed not Child class variable. 

Child child=new Child(); 
System.out.println(child.state); 

//in that case reference type is Child so Child class variable is accessed not Parent class variable. 

Parent parent=new Parent(); 
System.out.println(parent.state); 

//in that case reference type is Parent so Parent class variable is accessed not Child class variable. 

Ich hoffe, dass diese Lösung Ihnen helfen wird. Danke

Verwandte Themen