2015-03-30 6 views
3

Предположим, у меня есть класс ParkingMeter и класс ParkingSlip. Стоянки должны создаваться только из класса ParkingMeter, но ParkingSlips должен быть доступен внешним классом под номером Car (так что вы можете проверить, заплатил ли каждый автомобиль за парковку).Как вы обеспечиваете создание экземпляра класса только из определенного класса?

Есть ли способ гарантировать, что ParkingSlips может быть создан только в пределах ParkingMeter, но доступен для других классов?

+1

Используйте частный конструктор для парковки. http://stackoverflow.com/questions/17342815/what-is-the-use-of-private-constructor-in-java – chiaboy

+2

Сделайте ParkingSlips частным внутренним классом в ParkingMeter. Затем напишите метод getter, чтобы получить ParkingSlips (а не сеттер). Возьмите автомобиль, чтобы получить геттер в ParkingMeter –

+2

Да, конечно. Вы можете увидеть Внутренний класс: https: //docs.oracle.com/javase/tutorial/java/javaOO/innerclasses.html. Вы можете сделать ParkingSlip внутренним классом ParkingMeter. Автомобиль может получить объект ParkingSlip через геттер. – MageXellos

ответ

2

Если вы не хотите делать внутренний класс ParkingSlip, поместите два класса в один и тот же пакет и сделайте конструктор конструктора ParkingSlip-private. Он не остановит другие классы в одном пакете от создания парковочных листов, но он остановит злодеев в других пакетах.

package parking; 

public class ParkingSlip { 
    ParkingSlip() { 
    } 
} 

public class ParkingMeter { 
    public ParkingSlip getSlip() { 
     return new ParkingSlip(); 
    } 
} 
2

Самый безопасный способ сделать ParkingSlip общественный внутренний статический класс ParkingMeter и дать ему закрытый конструктор.

public class ParkingMeter { 
    public static class ParkingSlip { 
     private ParkingSlip() { 
     } 
    } 
} 

Менее безопасные, но более полезный, способ дать по умолчанию (так называемый «пакет») видимости конструктору и имеет ParkingMeter в том же пакете, но и любой другой класс из того же пакета - даже с другой проект - будет иметь доступ к конструктору.

Обратите внимание, что какой бы путь вы ни выбрали, отражение может обходить его.

1

На самом деле есть способ проверить, кто называется конструктор или метод:
по следственным текущему стеку.
Не то, что я рекомендовал бы это, но эй, это работает:

public ParkingSlip() { 

    // get the current stack trace 
    // element 0: java.lang.Thread.getStackTrace 
    // element 1: this constructor 
    // element 2: the class/method calling this constructor 
    StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); 

    // verify that it was indeed the ParkingMeter who invoked the constructor 
    if (!ParkingMeter.class.getName().equals(stackTrace[2].getClassName())) { 
     throw new IllegalAccessError("Restricted access, only ParkingMeter is allowed to create instances"); 
    } 
} 

чистое решение, который resticts доступ конструктора во время компиляции (решение выше только во время выполнения проверок) является

  • место ParkingMeter и ParkingSlip (только те два) в специальном пакете
  • оставить оба класса public
  • сделать конструктор (ы) е или ParkingSlip «дружественный» (ни private, ни protected, ни public)

Это гарантирует, что ParkingSlip конструкторы могут быть доступны только по классам в том же пакете, а также ParkingMeter является единственным классом в этом пакете, у вас есть то, что вы хотите.

public class ParkingSlip { 

    // 'friendly' constructor 
    ParkingSlip() { 
    } 
} 
Смежные вопросы