Почему есть доступ к приватной переменной другого класса?

Рейтинг: 0Ответов: 3Опубликовано: 23.03.2023
public static void main(String[] args) {
    dog haski = new dog();
    haski.name = "sobaka";
    haski.age = 3;
    haski.info();
}

static class dog{
    String name;
    private int age;
    private void info(){
        System.out.println(name+"|"+age);
        }
}

Работаю в intellij idea. Выдаёт тройку, хотя вроде как нельзя обращаться к переменной напрямую, если она приватная. Не понимаю, в чём проблема?

Ответы

▲ -2Принят

вот верный код

public class Main {
    public static void main(String[] args) {
        Dog haski = new Dog();
        haski.name = "sobaka";
        haski.setAge(3);
        haski.info();
    }
}

class Dog {
    String name;
    private int age;

    public void setAge(int age) {
        this.age = age;
    }

    public void info() {
        System.out.println(name + "|" + age);
    }
}
▲ 1

Код, приведённый в другом ответе, не является "правильным", равно как и код из вашего вопроса не является "неправильным".

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

public class Test {
    static class NestedClass {

    }

    class InnerClass {

    }
}
public class Main {
    public static void main(String[] args) {
        new Test.NestedClass(); // работает
        new Test().new InnerClass(); // работает
        // new Test.InnerClass(); // ошибка! Объект от InnerClass не может быть создан отдельно от объекта класса Test
    }
}

Класс, находящийся в другом классе и являющийся static, называется вложенным (nested) классом.
Класс, находящийся в другом классе и не являющийся static, называется внутренним (inner) классом.

Разница между ними в том, что первый для создания объекта не требует объекта от своего обрамляющего класса, а второй - требует. Нельзя создать объект inner-класса отдельно от объекта обрамляющего класса.

Говорить, какой из них "правильный", а какой "неправильный" - некорректно, так как это просто совершенно разные классы с разным назначением.

Ну а касательно обращения к приватным членам я уже ответил в комментариях. Обрамляющий класс имеет доступ к приватным полям и методам находящихся в нём классов, будь они с модификатором static или нет.

▲ 0

Пусть класс, в котором находиться метод main(), будет называться Test. В общем, код на самом деле у вас выглядел так:

public class Test {

    public static void main(String [] args){
         //Здесь вы создаёте объекты
    }

    static class Dog {
        //Поля и методы
    }

}

Что происходит в вашем коде

  • У вас есть класс Test;

  • Внутри класса Test есть класс Dog. Именно внутри. Ведь класс Dog в данном случае - статический вложенный класс (если на английском - то static nested class).

  • Метод main() находиться внутри класса Test. А внешний класс (Test) имеет доступ ко всем полям вложенного (Dog), в том числе и к приватным. Вот и ответ на ваш вопрос. Кстати, сам статический вложенный класс имеет доступ только к статическим полям внешнего.

Как должен был выглядеть ваш код

В данном случае использовать статический вложенный класс не стоит. Лучше сделать класс Dog обычным (невложенным) классом. Почему? Потому что собака - отдельная сущность, никак не связанная с сущностью класса Test, и нет никаких других причин помещать класс Dog в класс Test.