Solution 1 :
If you want only one instance of an object you can use object
keyword in Kotlin. It implements Singleton
pattern:
class App : Application {
val root = Root
}
object Root {
fun createObject(): Any {}
}
Now we can access to one instance of Root
class either by a property in App
class or via Root
class: Root.createObject()
UPDATE:
To implement a singleton that only one specific class has access to, we can use an interface and hide its implementation in that specific class (the maker class):
interface IRoot {
// ... methods of creation different objects for dependency injection
}
class App : Application {
val root: IRoot = Root
// hide implementation of `IRoot` interface in `App` class
private object Root : IRoot {
// ... implementation of methods of creation different objects for dependency injection
}
}
Problem :
I want to have a class that can only be instantiated by another class. I know I have to make the constructor
private otherwise everyone can instantiate it.
class Root private constructor() {
}
class RootMaker: Application() {
fun createRoot() = Root()
} // but this doesn't work because Root's constructor is private
one workaround is to make the maker
class, the inner class of the Root
class.
class Root private constructor() {
class RootMaker: Application() {
fun createRoot() = Root()
}
}
but I really don’t want to do this because the maker class is my application
class in android. so what is the better way?
Comments
Comment posted by Ghost
You could make the constructor
Comment posted by XY Problem
What is the reasoning behind your request, because I do have to wonder if this represents an
Comment posted by Slaw
Short of inspecting the stack trace of the calling thread, and assuming that
Comment posted by Slaw
Neither Java nor Kotlin have a direct mechanism to enforce “only this class can instantiate this other class”. The best you can do, while not resorting to hacks, is to strategically use visibility modifiers. And Kotlin annoyingly does not support package-private visibility. Your options include: (1) Document the usage requirements and make sure to use the API correctly, (2) inspect the stack trace to check the caller, (3) use reflection to instantiate, or (4) use the “friend accessor” pattern (not sure it this pattern works in Kotlin). There may be some other approach I’m missing.
Comment posted by wiki.apidesign.org/wiki/APIDesignPatterns:FriendPackages
Here’s an example of the “friend accessor” pattern in Java:
Comment posted by Mohsen
the problem is I want only one class to be able to get the instance, I’m not asking for singleton here. it is a singleton that only one specific class has access to its instance
Comment posted by Mohsen
I assume by
Comment posted by Sergio
No, in the comments you mentioned “the Root class is my CompositionRoot class for creating instances of other classes for dependency injection”, so by
Comment posted by Mohsen
thanks this is actually what I needed. and instead of constructor one can use invoke() function on the interface