java - защищенные члены, доступные в производном классе с использованием экземпляра базового класса - PullRequest
6 голосов
/ 30 июня 2010

Я создал экземпляр базового класса в производном классе и попытался получить доступ к защищенным членам.

Я могу получить прямой доступ к защищенным членам в производном классе без создания экземпляра базового класса.

Базовый класс:

package com.core;

public class MyCollection {

      protected Integer intg;
}

Производный класс в том же пакете -

package com.core;

public class MyCollection3 extends MyCollection { 

 public void test(){

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

Производный класс в другом пакете -

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
 }
}

Как можно получить доступ к защищенному члену базового класса в производном классе, используя экземпляр базового класса, когда производный класс также находится в том же пакете, но не когда производный класс находится в другом пакете?

Если я отмечу защищенный член как «статический», тогда я получу доступ к защищенному члену базового класса, используя экземпляр базового класса в производном классе, который находится в другом пакете.

Ответы [ 6 ]

10 голосов
/ 30 июня 2010

Вы правы, что не можете этого сделать. Причина, по которой вы не можете получить доступ к полю, заключается в том, что вы находитесь не в том же пакете, что и класс, и не имеете доступа к унаследованному члену того же класса .

Последний пункт является критическим - если бы вы написали

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

тогда это будет работать, так как вы изменяете защищенный член вашего собственного класса (который присутствует в этом классе посредством наследования). Однако в вашем случае вы пытаетесь изменить защищенный член другого класса в другом пакете. Поэтому неудивительно, что вам отказано в доступе.

3 голосов
/ 24 марта 2015

Если член класса protected, то есть 2 случая:

  1. Если подкласс находится в одном пакете
  2. Если подкласс находится в другом пакете

I.Тот же пакет:
- Может получить доступ через наследование.
- Может получить доступ, создав экземпляр родительского класса
II.Различные пакеты:
- Может только доступ через наследование

См. Таблицу ниже для всех случаев использования:

enter image description here

3 голосов
/ 30 июня 2010

В руководстве по Java написано:

Защищенный модификатор указывает, что доступ к элементу возможен только в его собственном пакете (как в пакете private), и, кроме того,подклассом своего класса в другом пакете.

И в вашем случае вы обращаетесь к переменной в другом объекте.По совпадению у него есть класс, который совпадает с текущим, но проверки видимости не проверят это.

Итак, во второй раз вам отказывают в доступе, потому что вы находитесь в другом пакете, и в первый раз, когда вам дают доступ, потому что вы находитесь в том же пакете (а не потому, что это подкласс)

1 голос
/ 30 июня 2010

Короче говоря, это не совсем возможно.Похоже, вам следует пересмотреть свой дизайн.

Однако, есть обходной путь, если вы уверены, что это то, что вы хотите сделать.Вы можете добавить защищенный метод к MyCollection, который берет экземпляр и устанавливает значение intg от вашего имени:

package com.core;

public class MyCollection {

    protected Integer intg;

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

Теперь ваши подклассы могут получить доступ к этому методу:

package secondary;

import com.core.MyCollection;

public class MyCollection2 extends MyCollection{ 

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

Но учтите, что это очень странный способ сделать это.Я бы еще раз предположил, что перед тем, как идти по этому пути, необходимо переосмыслить ваш дизайн.

0 голосов
/ 06 июня 2014

Вы не можете получить доступ к защищенной переменной в производном классе (который находится в другом пакете), если доступ осуществляется с использованием нового объекта класса MyCollection.Вы можете просто написать intg = 1;прямо без создания (новая коллекция MyCollection), например:

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

 public void test(){

     intg = 1;

 }
}
0 голосов
/ 30 июня 2010

В соответствии с правилом доступности члена Java вы не можете получить доступ к защищенному члену класса, не расширив его.

Вы можете попробовать следующее.

package secondary;

import com.core.MyCollection;

public class MyCollection2 extends MyCollection{ 

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

Вместо создания нового экземплярапопробуйте присвоить значение.Это будет работать.

...