2010-06-30 9 views
6

Ich habe die Instanz der Basisklasse in der abgeleiteten Klasse erstellt und versucht, auf geschützte Member zuzugreifen.Java - geschützte Member, auf die in der abgeleiteten Klasse mithilfe der Basisklasseninstanz zugegriffen wird

Ich kann direkt auf geschützte Member in einer abgeleiteten Klasse zugreifen, ohne die Basisklasse instanziieren.

Basisklasse:

package com.core; 

public class MyCollection { 

     protected Integer intg; 
} 

Eine abgeleitete Klasse im selben Paket -

package com.core; 

public class MyCollection3 extends MyCollection { 

public void test(){ 

    MyCollection mc = new MyCollection(); 
    mc.intg=1; // Works 
} 
}

Eine abgeleitete Klasse in einem anderen Paket -

package secondary; 

import com.core.MyCollection; 

public class MyCollection2 extends MyCollection{ 

public void test(){ 
    MyCollection mc = new MyCollection(); 
    mc.intg = 1; //!!! compile time error - change visibility of "intg" to protected 
} 
} 

Wie ist es möglich, Zugang ein geschütztes Mitglied einer Basisklasse in einer abgeleiteten Klasse, die die Instanz der Basisklasse verwendet, wenn die abgeleitete Klasse ebenfalls in s ist ein Paket, aber nicht, wenn die abgeleitete Klasse in einem anderen Paket ist?

Wenn ich protected member als "static" markiere, kann ich mit einer Instanz der Basisklasse in einer abgeleiteten Klasse, die sich in einem anderen Paket befindet, auf das geschützte Member der Basisklasse zugreifen.

+0

möglich Duplikat [Java Protected Access funktioniert nicht] (http://stackoverflow.com/questions/332920/java-protected-access-not-working) --- Eigentlich ist das der falsche Betrogene! Es tut uns leid! Dies ist jedoch definitiv ein Betrogener. – polygenelubricants

+0

keine Sorge, Ihre IDE wird keinen Unterschied in der Frage machen, da es sich um die Semantik der Java-Sprache selbst handelt. –

+0

mögliches Duplikat von [Warum kann ich nicht auf geschützte Java-Methode zugreifen, auch wenn ich die Klasse erweitert habe?] (Http://StackOverflow.com/questions/1622219/why-cant-i-access-protected-java-method -even-think-ive-extended-the-class) – starblue

Antwort

10

Sie haben Recht, dass Sie das nicht tun können. Der Grund, warum Sie nicht auf das Feld zugreifen können, besteht darin, dass Sie nicht im selben Paket wie die Klasse sind oder auf ein geerbtes Mitglied der gleichen Klasse zugreifen.

Der letzte Punkt ist die kritische - wenn Sie

geschrieben haben
MyCollection2 mc = new MyCollection2(); 
mc.intg = 1; 

dann würde dies umgehen, wie Sie ein geschütztes Mitglied der Ihre eigenen Klasse sind zu ändern (was in dieser Klasse vorhanden ist durch Vererbung). In Ihrem Fall versuchen Sie jedoch, ein geschütztes Mitglied einer anderen Klasse in einem anderen Paket zu ändern. Daher ist es nicht verwunderlich, dass Ihnen der Zugriff verweigert wird.

+0

Diese Erklärung ist wirklich einfach zu verstehen. Ich habe mir die Java-Sprachspezifikation angeschaut und ihre Ausarbeitung ging über meinen Kopf !!! – Tarun

+0

@Tarun - Wenn eine Antwort für Sie funktioniert hat, markieren Sie sie als akzeptiert (klicken Sie unter dem Abstimmungszähler) – Bozho

+0

Ich kannte diese Funktion nicht. Ich würde es als beantwortet markieren. – Tarun

0

Gemäß der Zugriffsregel für Elemente von Java können Sie nicht auf geschützte Member einer Klasse zugreifen, ohne sie zu erweitern.

Sie können Folgendes versuchen.

package secondary; 

import com.core.MyCollection; 

public class MyCollection2 extends MyCollection{ 

public void test(){ 
    intg = 1; 
} 
} 

Anstatt die neue Instanz zu erstellen, versuchen Sie, den Wert zuzuweisen. Es wird klappen.

+0

Stimmen Sie mit Ihrer Argumentation überein – Tarun

3

Die Java tutorial sagt:

Der geschützte Modifikator gibt an, dass das Element kann nur innerhalb des eigenen Pakets zugegriffen werden (wie bei Paket-privaten) und zusätzlich durch eine Unterklasse der Klasse in einem anderen Paket .

Und in Ihrem Fall greifen Sie auf die Variable in einem anderen Objekt zu. Durch Zufall hat es eine Klasse, die die gleiche wie die aktuelle ist, aber die Sichtbarkeitsüberprüfungen würden das nicht überprüfen.

So, das zweite Mal, wenn der Zugriff verweigert werden, weil Sie in einem anderen Paket sind, und das erste Mal, wenn Sie den Zugriff gegeben werden, weil Sie im selben Paket sind (und nicht, weil es eine Unterklasse)

+0

"das erste Mal erhalten Sie Zugriff, weil Sie im selben Paket sind (und nicht weil es eine Unterklasse ist)" Das macht es für mich klar. Vielen Dank. – Tarun

1

In Kurz, es ist nicht wirklich möglich. Es scheint, als ob du dein Design überdenken solltest.

Es gibt jedoch eine Arbeit, wenn Sie sicher sind, dass Sie das tun möchten. Sie können eine geschützte Methode-MyCollection hinzufügen, die eine Instanz nimmt und setzt den Wert von intg in Ihrem Namen:

package com.core; 

public class MyCollection { 

    protected Integer intg; 

    protected void setIntg(MyCollection collection, Integer newIntg) { 
     collection.intg = newIntg; 
    } 
}

Jetzt ist Ihre Unterklassen diese Methode zugreifen können:

package secondary; 

import com.core.MyCollection; 

public class MyCollection2 extends MyCollection{ 

    public void test(){ 
     MyCollection mc = new MyCollection(); 
     setIntg(mc, 1); 
    } 
}

Aber bitte beachten Sie, dass Dies ist eine sehr seltsame Art und Weise, es zu tun. Ich würde vorschlagen, dass Ihr Design neu überdacht werden muss, bevor Sie diesen Weg gehen.

+0

Ich verstehe Ihren Standpunkt. Der einfachste Weg für mich wäre, direkt auf das geschützte Member zuzugreifen, anstatt die Basisklasse zu instanziieren und in einem anderen Paket darauf zuzugreifen. Ich habe es beim Spielen mit Java "irrtümlich" gemacht (habe ich nicht gesagt, dass ich ein Manault Tester bin :-)) und dann konnte mir keiner meiner Dev-Mitglieder eine denkbare Antwort geben. Also habe ich es hier gepostet. – Tarun

0

Sie können auf eine geschützte Variable in einer abgeleiteten Klasse (die sich in einem anderen Paket befindet) nicht zugreifen, wenn Sie mit einem neuen Objekt der Klasse MyCollection darauf zugreifen. Sie können einfach schreiben intg = 1; direkt ohne (neue MyCollection) machen wie folgt aus:

package secondary; 
import com.core.MyCollection;  
public class MyCollection2 extends MyCollection{ 

public void test(){ 

    intg = 1; 

} 
} 
3

Wenn eine Klasse Mitglied protected ist, dann gibt es zwei Fälle:

  1. Wenn Unterklasse in demselben Paket ist
  2. Wenn Unterklasse ist in anderem Paket

I. Dasselbe Paket:
- Kann durch Vererbung zugreifen
- Kann durch Erstellen einer Instanz der Elternklasse zugreifen
II. Verschiedene Paket:
- Can nur Zugang durch Vererbung

Siehe Tabelle unten für alle Anwendungsfälle:

enter image description here

Verwandte Themen