4

Is there any language or language feature where you can re-call the constructor on an instance of a class and is there any reason why you don't want to do this?

For example,

//let's say you have this:
var person = new PersonModel("John", "Doe");

// is it possible to do this:
person.constructor("Jane", "Doe");

Reason:
I'm writing code and I have a case where I have reusable objects (data objects in collection) and being able to update the object through the constructor parameters would be an easy way to update the data object for me for right now in my specific case. I know I can break the code up if to do the same thing.

Longer Reason:
I'm creating a Collection View in C# in Xamarin that wraps NSCollectionView (think grid layout in HTML) and I wanted to prepopulate the grid with ten items for the user to see and click on. So these are placeholder items because the Collection View won't be created unless it has data. But the items are like images. They have to be loaded. So I have to have data, even dummy data, to create the view.

So, I created the Data Value Objects or Data Models to create the grid of items. Then when the user clicks on the grid item I can load in an image. So since I already have the data object and simply need to load in content I want to reuse it. It wouldn't mess up the layout or any animations or anything else that creating a new object might.

It would take one line of code if I could reuse the object compared to about 100 lines of code to break out the constructor and other related things like create a new instance with the new information.

I've done the break code in the past. It occurred to me to ask if this is possible bc I had similar use cases like this a few times ...and because JavaScript breaks so many paradigms that maybe it was possible in some languages. Because JS has the myMethod.apply() and if a constructor is just a method would object.constructor.apply() work.

11
  • 1
    @TulainsCórdova: I read the "is there any language" question not as a request for "help me pick what language I should use", and more as a "I am thinking of this approach, has this been done before?", which is perfectly on topic and structurally no different from a question where an OP is trying to vet their approach, not knowing there is a design pattern for that specific use case. I don't think the question needs rephrasing to avoid closure.
    – Flater
    Commented Jun 7, 2021 at 8:23
  • 3
    You can do that in Python, since the constructor (__init__) is really just an ordinary method which is automatically called after creating an instance. You can call it manually later if you want. Wouldn't recommend it though.
    – JacquesB
    Commented Jun 7, 2021 at 10:01
  • 2
    How can an object be born when he is old? Can he enter the second time into his constructor's scope, and be born?
    – trent
    Commented Jun 8, 2021 at 15:00
  • 1
    @trentcl 🤣 indeed he must be instantiated again Commented Jun 9, 2021 at 2:14
  • 1
    I mean assign a freshly constructed object to the original.
    – Caleth
    Commented Jun 10, 2021 at 7:11

3 Answers 3

8

A constructor is meant to initialize an object — set its initial state. Re-calling a constructor is not possible in languages that allow the programmer to mark an instance variable as readonly, final, or const.

And then there is JavaScript.

With JavaScript you can call a constructor after the object has been initialized. The call method of a Function object allows you to pass an object as the first argument, which is used as this inside the function call.

let person = new Person("John", "Doe")

Person.call(person, "Jane", "Doe")

You can do this in JavaScript because it does not use true classes (and a class in ECMA Script is not a true class either), nor is JavaScript a strongly typed language. It uses prototypal inheritance, which means new objects are created from existing objects, not classes. A constructor in JavaScript borders on being just another function, but is invoked at a specific point in an object's life.

That being said, your problem seems to be related to code repetition, not calling a constructor. Fortunately we have lots of options for code reuse. Consider adding a public method that does the reinitializing, and call that method from the constructor. Clearly you have a use case where reusing an entire object is desirable, so you probably do not need to worry about readonly fields.

So just make it easy on yourself. DRY up your code by putting the initialization logic in a public method and have your constructor call it.

1
  • It is because of JavaScript I posted this question lol. I added more background details about it. Commented Jun 7, 2021 at 23:57
4

Yes, in C++ you may invoke a placement new to construct an object in the same memory location as an existing object.

However the lifecylcle rules require you to first destruct the existing object before placing something in its memory.

This technique allows you to replace an object by invoking a constructor. But this is risky, since you need to be sure that the memory layout of the placed object fits into the memory of the old object and not forget about the destructor. In practice, there is only one case where this kind of replacement makes sense: the case of a union when you switch from one member of to another member that is a class (see this SO answer, with a quote and example out of the standard).

In all other cases, whenever you feel that you have to invoke a constructor, you should wonder if you should not considered more composition in your class design.

1

No.

Well, I can't cover every possible language in existence, but no it is not a common feature or design principle in any language I've ever heard of. Except Javascript, but JS is a fine example of giving developers much more access than good reason would dictate. "It can be done in JS" is not equivalent to "It is a good idea to do this in JS".

But there are two thoughts that come to mind here:

1. It's easily worked around using a method

public class Foo
{
    public Foo(int x, string y)
    {
        MyLogic(x,y);
    }

    public void MyLogic(int x, string y)
    {
        // Whatever constructor logic you would've had
    }
}

However, this does not play nicely with readonly fields.

I would expect that your intended purpose very much takes into account that all of your class fields/properties should be "resettable", since you want to "reset" your object, so you wouldn't be using any readonly fields to begin with.

2. Why would you want to?

This is the bigger issue for me. You seem to understand that a constructor is an initialization algorithm and sets the object to its initial state. That is correct.

But then why are you invested in "resetting" an existing object, when you can't find a way to do so; while you could just as easily just create a new object and discard the old one?

In essence, what's wrong with this code instead:

var person = new PersonModel("John", "Doe");

// We want to change our person now
person = new PersonModel("Jane", "Doe");

I'm writing code and I have a case where I have reusable objects (data objects in collection) and being able to update the object through the constructor parameters would be an easy way to update the data object for me for right now in my specific case.

I don't quite see how you can't just overwrite one object with another. Unless you're using readonly (or similar write-protecting features), but then the solution is to stop blocking the ability to overwrite one object with another.

right now in my specific case

This is just a tip, because I suspect you're trying to approach this in a way that I used to approach development back when I got started. With hindsight, I would tell my younger self:

One thing you learn as a developer is that overfitting, i.e. trying to really custom tailor something to your particular situation, is less effective, because you've spent time creating and now have something that is so uniquely fit for the job at hand, that it has no purpose in any other scenario.

Conformity tends to win the day in the long run. Stick to good practice and perfectly acceptable code, in this case instantiating a new object, rather than trying to reinvent the constructor and how it works.

While it may not be the ultimate min-max for your current situation, it is a very versatile approach which will apply in many scenarios, and therefore you will over time use it more and more and gain much more confidence experience with it.
This is much more useful to you as a developer, as opposed to only having built highly custom implementations that do not carry over into your future experiences.

1
  • I've added more details to my question on the why Commented Jun 7, 2021 at 23:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.