Пакетная видимость (package-private) и protected

Тренажер по Java для пользователей с начальным уровнем подготовки.

Тренажер по Java

Модификаторы доступа в Java управляют видимостью классов и их членов. package-private — это доступ «по умолчанию» (если не писать модификатор): элемент доступен только внутри того же пакета. protected расширяет доступ: внутри пакета — как package-private, а также из классов-наследников в других пакетах. В этом практическом уроке/тренажере вы научитесь читать и исправлять модификаторы, понимать, что будет доступно при наследовании, и как это влияет на разработку. Пример: protected int id; в базовом классе.

  • Без модификатора → package-private
  • protected полезен для API базовых классов
  • Видимость определяется пакетом и наследованием
Список тем

1. Сделайте член package-private

id: 40484_m8_vis_01_replace_default_access

В Java для объявления члена класса с уровнем доступа package-private (по умолчанию) не нужно указывать модификатор — достаточно написать тип и имя. Такой член будет доступен только внутри того же пакета. В классе Storage часть полей и методов уже объявлена с явными модификаторами (private, protected). Дополните код, вписав объявления package-private членов без использования модификаторов доступа. Обратите внимание на комментарии, где указаны требуемые типы и имена.

Заполните пропуски
package com.company.storage;

class Storage {
    private String secretKey;
    input1S;                    // package-private String name
    protected int capacity;

    input2S {                   // package-private void clear()
        name = "";
        capacity = 0;
    }

    input3S {                   // package-private String getName()
        return name;
    }
}
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

2. Добавьте protected

id: 40484_m8_vis_02_replace_protected_keyword

В этом задании вам нужно правильно использовать модификатор доступа protected, чтобы обеспечить доступ к полю базового класса из класса-наследника, находящегося в другом пакете. Изучите код, в котором базовый класс Animal и класс-наследник Dog находятся в разных пакетах. Вам необходимо вставить ключевое слово protected в объявление поля базового класса, чтобы код компилировался и работал корректно. Обратите внимание на комментарии, которые указывают, где именно требуется внести изменения.

Заполните пропуски
// Базовый класс в пакете animals
package animals;

public class Animal {
    // Объявите поле name с модификатором, который разрешит доступ из наследника в другом пакете
    input1S String name;
    
    public Animal(String name) {
        this.name = name;
    }
}

// Класс-наследник в пакете pets (другой пакет)
package pets;

import animals.Animal;

public class Dog extends Animal {
    public Dog(String name) {
        super(name);
    }
    
    public void printName() {
        // Этот метод должен иметь доступ к полю name из базового класса
        System.out.println("Dog's name: " + name);
    }
}

// Класс Main для демонстрации
public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog("Buddy");
        dog.printName(); // Ожидаемый вывод: Dog's name: Buddy
    }
}
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

3. Исправьте неверный модификатор

id: 40484_m8_vis_04_error_incorrect_access

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

Найдите ошибку и исправьте
// package a;
public class Parent {
    void display() {
        System.out.println("Parent display");
    }
}
 
// package b;
public class Child extends Parent {
    public void show() {
        display();
    }
}
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

4. Сопоставьте модификатор и область видимости

id: 40484_m8_vis_05_compare_rules

Сопоставьте каждый модификатор доступа или особый случай из левой колонки с кратким описанием его области видимости из правой колонки. Обратите внимание на ключевые различия между package-private (модификатор по умолчанию), protected и частным случаем protected вне пакета.

Сопоставьте строки в правой(нижней) части с соответствующими строками в левой(верхней) по порядковому номеру
private
package-private (default)
protected
public
protected вне пакета через наследование
Доступ внутри того же пакета (модификатор не указан).
Доступ внутри пакета и в подклассах (даже из других пакетов).
Доступ только внутри того же класса.
Доступ в подклассах другого пакета, но только через наследование (не по ссылке на объект родителя).
Доступ отовсюду, где виден класс.
Сообщения
Проверить
Показать подсказку

5. Скомпилируется ли обращение?

id: 40484_m8_vis_06_predict_result_compile_or_not

Проанализируйте приведённый код на Java, который демонстрирует попытку доступа к protected полю из класса, находящегося в другом пакете. Обращение происходит через ссылку на объект родительского класса. Определите, будет ли такой код скомпилирован, и выберите соответствующий вариант ответа, объясняющий причину ошибки или её отсутствие.

Выберите правильный вариант ответа
// Файл A.java в пакете p1
package p1;

public class A {
    protected int value;
}

// Файл C.java в пакете p2
package p2;

import p1.A;

public class C extends A {
    public void test() {
        A obj = new A();
        int x = obj.value;  // Будет ли это компилироваться?
    }
}
Сообщения
Проверить
Показать подсказку

6. Соберите пример с protected и пакетом

id: 40484_m8_vis_07_build_from_parts_two_classes

Из предложенных строк соберите корректную java-программу, которая демонстрирует доступ к членам класса с модификаторами package-private и protected из подкласса в том же пакете. Программа должна включать объявление пакета, базовый класс с package-private и protected членами, подкласс, который обращается к этим членам. Лишняя строка с объявлением private члена не должна входить в решение.

Перетяните в правильном порядке строки из одного блока в другой
package com.example;
class BaseClass {
    int packagePrivateVar;
    protected int protectedVar;
    private int privateVar;
}
class SubClass extends BaseClass {
    void access() {
        protectedVar = 10;
        packagePrivateVar = 20;
    }
}
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

7. Разложите утверждения по категориям

id: 40484_m8_vis_08_sort_access_by_scope

Перед вами список утверждений, описывающих область видимости членов класса в Java. Распределите каждое утверждение по одной из трёх категорий: 'Только внутри класса', 'Внутри пакета' или 'Вне пакета (через наследование)'. Учтите, что в Java модификаторы доступа (private, package-private, protected) определяют, где можно использовать поле, метод или конструктор. Каждое утверждение однозначно соответствует одному из этих модификаторов.

Перетяните элементы в соответствующие блоки
Только внутри класса
Внутри пакета
Вне пакета (через наследование)
Доступ к члену класса возможен только из того же класса.
Подклассы не могут обращаться к этому члену класса.
Классы, находящиеся в том же пакете, не имеют доступа к этому члену.
Член класса доступен из любого класса в том же пакете.
Член класса не доступен из подклассов, находящихся в другом пакете.
Член класса не доступен из классов другого пакета, не являющихся подклассами.
Член класса доступен из подклассов, даже если они находятся в другом пакете.
Подклассы из другого пакета могут наследовать этот член класса.
Для доступа к этому члену из другого пакета необходимо, чтобы класс был подклассом.
Сообщения
Проверить
Показать подсказку
НайтиКурс.Ру