Let’s say I have an “abstract” class called Base, and several others classes Class1, Class2, Etc. that inherit from the Base class. I want to be able to create instances of Class1, etc. from a shared method in the Base class. e.g. I have a shared method in Base:
function Instance() as Base
I would like to be able to call
dim c as Class1 = Class1.Instance
and return a Class1 instance, without having every class have its own Instance method.
I have not been able to figure out if this is doable or not. Introspection seems only to be able to construct information from either an object of a class, or from a call to GetTypeInfo with the name of the class as parameter.
Any reason you don’t just do this:
Dim c as new Class1
It’s idiomatic and I think more understandable…
Well, the reason for this “theoretical” discussion is so that all of Base’s subclasses can only have a single instance, which I would enforce via the Instance method (i.e. if an instance already exists, return it, otherwise create a new object).
Sure I could implement this separately for every subclass, but it gets tedious and prone to error.
If you are trying to manage instances of these various classes, I would put that code in the base class constructor.
All you have to do then is make sure the sub class constructor ( if one exists ) is to call super.constructor.
The actual management of the instances can be in a shared method in the base class.
That’s an interesting take. However it means creating an object that, if one of the class already exists, would need to get thrown away. Also there is no way to return the shared instance from the constructor. i.e. with
dim c as new Class1
you’d always end up with a new object.
Looks like our replies crossed. What you were asking about is called a “singleton” pattern, and there are tons of ways to do that.
I am on mobile right now, so I can’t really give you an examples, but I’m sure this has been asked and answered before in the forums
Yes, if each subclass implements it’s own shared system, but I want to do it from a base class shared system. Can’t think of any way to do it in Xojo. Easy enough in say, Swift.
Anyway I might have to bite the bullet and do it multiple times.
function Class1.shared as Class1
Static c as new Class1
Also, to prevent someone accidentally creating New Class1 you can create a constructor and set it to private
Correction, it looks like you can’t use “Shared()” as the method name, because that’s a reserved word in Xojo. (I chose ‘Shared’ because that’s how Swift does it).
Here’s a cleaned up version that actually compiles:
Public Shared Function SharedInstance() As Class1
static c as new Class1 // Static variables are Application-global, so the "new" will only happen once
Private Sub Constructor()
// by making the constructor Private, we prevent code from creating a new instance.
// e.g. this code
// dim C as new Class1
// will no longer compile outside of Class1
If you wanted to do the bookkeeping in the Base class, I think that’s possible, but not necessarily any less code to write.
OK, so the particular Base class I’m looking at is a subclass of DesktopWindow, so the singleton code is a bit more complex since you need to reconstruct the DesktopWindow if it was subsequently closed, requiring nil-ing the instance property when the window closes, which means a separate private shared instance variable rather than a static variable (although I guess one could use a WeakRef, with even more code).
Anyway, it would seem that there’s no way to encapsulate all this stuff in the Base class, so I’m gonna bite the bullet and just reproduce the code for each subclass of the Base class.
Isn’t this the use case for Implicit Instance?
- in the window CancelClose event, simply hide the window rather than closing it - later on you simply Show it rather than re-creating it. (You need to handle the case there the app is quitting, in which case you do need to close the window properly)
Mike is right. What you are describing is an Implicit Instance window, and Xojo already does all the heavy lifting for you.
Yes, but Implicit Instance is an abomination (IMHO). I don’t want these windows to hang around, hidden, and consuming resources. When I close them, I want them to go away.
Thanks for the suggestion though.