сделать класс доступным только для определенного класса

Допустим, у меня есть 3 класса class1, class2 и class3.

Как я могу сделать так, чтобы class1 мог быть создан только class2 (class1 object = new class1()), но не class3 или любым другим классом?

Я думаю, что это должно работать с модификаторами, но я не уверен.


person maddo7    schedule 16.01.2013    source источник
comment
Вам нужно, чтобы class1 был доступен для других классов, но не мог быть создан?   -  person Marc Baumbach    schedule 16.01.2013


Ответы (4)


Я хочу переименовать ваши классы в Friend, Shy и Stranger. Friend должен иметь возможность создать Shy, но Stranger не должен.

Этот код будет скомпилирован:

package com.sandbox;

public class Friend {

    public void createShy() {
        Shy shy = new Shy();
    }

    private static class Shy {

    }

}

Но этот код не будет:

package com.sandbox;

public class Stranger {

    public void createShy() {
        Friend.Shy shy = new Friend.Shy();
    }

}

Кроме того, если мы создадим новый класс с именем FriendsChild, он также не будет компилироваться:

package com.sandbox;

public class FriendsChild extends Friend {

    public void childCreateShy() {
        Shy shy = new Shy();
    }

}

И это соглашение об именах имеет смысл, если подумать. То, что я друг кого-то, не означает, что мой ребенок знает их.

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

person Daniel Kaplan    schedule 16.01.2013

Другой вариант, помимо защиты конструктора:

  • Сделать конструктор class1 закрытым
  • Создайте общедоступный статический фабричный метод, для которого требуется действительный экземпляр class2, чтобы вернуть экземпляр class1.
person Amir Afghani    schedule 16.01.2013

Сделать class1 внутренним классом class2.

person DcodeChef    schedule 16.01.2013

Обновить

создайте конструктор protected и поместите подходящий класс в тот же пакет, если вы хотите, чтобы какой-либо класс вне пакета создавал этот экземпляр, тогда вам нужно, чтобы этот класс расширил ClassA в этом примере,

если вы ограничиваете его, используйте спецификатор доступа default

package com.somthing.a;
public class ClassA {

    ClassA() {
        super();
        // TODO Auto-generated constructor stub
    }
}

package com.something.a;
public class ClassB {
    public static void main(String[] args) {
        new ClassA();//valid
    }
}


package com.something.c;
public class ClassC {
    public static void main(String[] args) {
        new ClassA();// invalid
    }
}
person jmj    schedule 16.01.2013
comment
Почему не частный конструктор пакета? - person Marko Topolnik; 16.01.2013
comment
Я не согласен с этим ответом. Если конструктор защищен, это означает, что класс, который его расширяет, все еще может вызывать конструктор. - person Daniel Kaplan; 16.01.2013