Хитрый protected

Хитрый protected

Члены класса с областью видимости protected доступны наследникам независимо от местонахождения этих наследников. Однако, доступ к protected-членам родительского класса по ссылочным переменным зависит от пакета, в котором определён наследник.

По ссылочным переменным protected-члены доступны наследникам из того же пакета. Но наследникам из другого пакета они недоступны.


package one;

public class ProtectedBook {
    protected String name = "ProtectedBook";
    
    protected void print(String text) {
        System.out.println(text);
    }
}


package one;

public class NoteBook extends ProtectedBook {
    public NoteBook() {
        name = "NoteBook";
        
        print("class NoteBook: name = " + name);
        ProtectedBook b = new ProtectedBook();
        String referName = b.name; /* по ссылочным переменным protected-члены доступны наследникам
                                        из того же пакета */
        b.print("class NoteBook: b.name = " + referName);
        
    }  
}


package two;

import one.ProtectedBook;

public class StoryBook extends ProtectedBook {
    
   public StoryBook() {
        name = "Story";
        print("class StoryBook: name = " + name);
        
        ProtectedBook b = new ProtectedBook();
        String  referName = b.name; // ошибка компиляции. По ссылочным переменным 
        b.print("class StoryBook: b.name = " + name); // protected-члены не доступны наследникам из других пакетов
    }
}


package one;

import two.StoryBook;

public class Main {
    public static void main(String[] args) {
       StoryBook s = new StoryBook();
       NoteBook n = new NoteBook();
    }
}
/*
Вывод:
class StoryBook: name = Story
class NoteBook: name = NoteBook
class NoteBook: b.name = ProtectedBook
*/
Основы Java