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

Рассмотрим большой пример. Пусть имеется пять классов, размещенных в двух пакетах, как показано на рис. 3.1.

Рис. 3.1. Размещение  наших классов по пакетам

В файле Base.java описаны три класса: inpi, Base и класс Derivedpi , расширяющий класс вазе. Эти классы размещены в пакете pi. В классе Base определены переменные всех четырех типов доступа, а в методах f() классов inp1 и Derivedp1 сделана попытка доступа ко всем полям класса вазе. Неудачные попытки отмечены комментариями. В комментариях помещены сообщения компилятора. Листинг 3.1 показывает содержимое этого файла.

Листинг 3.1. Файл Base.java с описанием пакета p1

package p1;

class Inp1{

  public void f () {

    Base b = new Base(); 

//    b.priv = 1;   // "priv has private access in p1.Base"

    b.pack = 1;

    b.prot = 1;

    b.publ = 1; 

  } 

}

public class Base{

  private int priv = 0; 

          int pack = 0;

protected int prot = 0;

   public int publ = 0; 

}

class Derivedpi extends Base{

  public void f(Base a) { 

// a.priv = 1; // "priv hds private access in pi.Base"

  a.pack = 1;

  a.prot = 1;

  a.publ = 1; 

//   priv = 1; // "priv has private access in pi.Base"

  pack = 1;

  prot = 1;

  publ = 1; 

  } 

}

Как видно из листинга 3.1, в пакете недоступны только закрытые, private , поля другого класса.

В файле Inp2.java описаны два класса: inp2 и класс Derivedp2 , расширяющий класс base . Эти классы находятся в другом пакете р2 . В этих классах тоже сделана попытка обращения к полям класса вазе. Неудачные попытки прокомментированы сообщениями компилятора. Листинг 3.2 показывает содержимое этого файла.

Напомним, что класс вазе должен быть помечен при своем описании в пакете p1 модификатором public , иначе из пакета р2 не будет видно ни одного его члена.

Листинг 3.2. Файл Inp2.java с описанием пакета р2

package p2; 

import pl.Base;

class Inp2{

  public static void main(String[] args){

    Base b = new Base();

// b.priv = 1;   // "priv has private access in pl.Base" 

// b.pack = 1;   // "pack is not public in pl.Base;

                 // cannot be accessed from outside package"

// b.prot = 1;   //„"prot has protected access in pi.Base"

b.publ = 1;

  }

}

class Derivedp2 extends Base{

public void, f (Base a){ 

// a.priv = 1;       // "priv has private access in. p1.Base" 

// a.pack = 1;       // "pack, is not public in pi.Base; cannot

                     //be accessed from outside package" 

// a.prot = 1;       // "prot has protected access in p1.Base"

 a.publ = 1;

// priv = 1;         // "priv has private access in pi.Base" 

// pack = 1;         // "pack is not public in pi.Base; cannot

                     // be accessed from outside package"

 prot = 1;

 publ = 1; 

 super.prot = 1; 

  } 

}

Здесь, в другом пакете, доступ ограничен в большей степени.

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

Все указанное относится не только к полям, но и к методам. Подытожим все сказанное в табл. 3.1.

Таблица 3.1. Права доступа к полям и методам класса

 


Класс

Пакет

Пакет и подклассы

Все классы

private

+

 


 


 


"package"

+

+

 


 


protected

 


 +

+

*

public

+

+

+

+

Особенность доступа к protected -полям и методам из чужого пакета отмечена звездочкой.