Я создал экземпляр базового класса в производном классе и попытался получить доступ к защищенным участникам.
Я могу непосредственно получить доступ к защищенным участникам в производном классе, не инстанцируя базового класса.
Базовый класс:
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
}
}
Как возможно получить доступ к защищенному члену базового класса в производном классе с помощью экземпляра базового класса, когда производный класс находится также в том же пакете, но не, когда производный класс находится в другом пакете?
Если я отмечаю защищенного участника как "статичного" затем, я могу получить доступ к защищенному члену базового класса с помощью экземпляра базового класса в производном классе, который находится в другом пакете.
Вы правы, что не можете этого сделать. Причина, по которой вы не можете получить доступ к полю, заключается в том, что вы не находитесь в том же пакете, что и класс, , и не имеете доступа к унаследованному члену того же класса .
Последний пункт является критическим: если бы вы написали
MyCollection2 mc = new MyCollection2();
mc.intg = 1;
, это сработало бы, поскольку вы меняете защищенный член вашего собственного класса (который присутствует в этом классе через наследование). Однако в вашем случае вы пытаетесь изменить защищенный член другого класса в другом пакете. Таким образом, неудивительно, что вам отказано в доступе.
В учебнике Java говорится:
Модификатор protected указывает, что к члену можно получить доступ только в его собственном пакете (как в случае с package-private) и, кроме того, подклассом своего класса в другом пакете.
И в вашем случае вы обращаетесь к переменной в другом объекте. По совпадению у него есть класс, который совпадает с текущим, но проверки видимости этого не проверят.
Итак, во второй раз вам отказывают в доступе, потому что вы находитесь в другом пакете, и в первый раз, когда вам предоставляется доступ, потому что вы находитесь в том же пакете (а не потому, что это подкласс)
Короче говоря, это невозможно. Похоже, вам стоит пересмотреть свой дизайн.
Однако есть обходной путь, если вы уверены, что хотите сделать именно это. Вы можете добавить защищенный метод в 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);
}
}
Но учтите, что это очень странный способ сделать это. Я снова предлагаю переосмыслить ваш дизайн, прежде чем вы пойдете по этому пути.
Согласно правилу доступности членов Java, вы не можете получить доступ к защищенному члену класса, не расширив его.
Вы можете попробовать следующее.
package secondary;
import com.core.MyCollection;
public class MyCollection2 extends MyCollection{
public void test(){
intg = 1;
}
}
Вместо создания нового экземпляра попробуйте присвоить значение. Это будет работать.