Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I wonder if can I say that a constructor is a special case of a method?
You can say anything. Whether anyone will disagree with you depends on the context. Some language communities and standards define things that way.
More elaborately, it depends on what you mean by a 'method.' In C++, for example, one way to analyze the creation process is to say that it consists of a call to an operator new (perhaps just placement) followed by a call to a constructor method. From an implementation standpoint, a constructor looks, walks, and quacks like a method. In some compilers, you can even invoke one explicitly.
From a more theoretical viewpoint, someone might claim that constructors are some distinctive species. However, there is no single, true, privileged conceptual model of methods, constructors, or purple unicorns.
Gosh this is all subjective.
You could say so, just as you can say that a human is a special case of animal, however in most contexts mentioning animals implies non-human animals and mentioning methods implies non-constructor methods.
Technically, a constructor usually is a method. Whether it really is or is not depends largely on the particular environment. For example, in .NET constructors are methods called actually after an object is created. However, it's also possible to create an object without having a constructor called right after.
Update: Regarding .NET, or the Common Language Infrastructure to be more precise, ECMA 335, section 8.9.6.6 Constructors states:
New values of an object type are created via constructors. Constructors shall be instance methods, defined via a special form of method contract, which defines the method contract as a constructor for a particular object type.
I think a constructor is too special to be called a method
It doesn't return anything
It modifies the object before the object is initialized
It cannot call itself (imagine that)
blah blah blah
There might be difference between languages, but I don't think I'm going as far as calling a constructor "special method".
In languages that have constructors, you can usually think of a constructor as a special case of a factory method. (Note: I don't mean the GoF Factory Method Software Design Pattern, I'm just talking about any class method that creates new instances.) Usually, this "special casing" generally takes the form of annoying restrictions (e.g. in Java, you can only call the parent constructor at the beginning of the constructor), which is why even in languages that do have constructors, you often end up using or writing factory methods anyway.
So, if constructors are basically factory methods with restrictions, there is really no need to have them both, and thus many languages simply get rid of constructors. Examples include Objective-C, Ruby, Smalltalk, Self, Newspeak, ECMAScript/JavaScript, Io, Ioke, Seph and many others.
In Ruby, the closest thing to a constructor is the method Class#allocate, which simply allocates an empty object and sets that object's class pointer. Nothing more. Since such an empty object is obviously unusable, it needs to initialized. Per convention, this initialization is performed by #initialize. As a convenience, because it is cumbersome to always have to remember to both allocate and initialize (as any Objective-C developer can probably attest), there is a helper method called Class#new, which looks something like this:
class Class
def new(*args, &block)
obj = allocate
obj.initialize(*args, &block)
return obj
end
end
This allows you to replace this:
foo = Foo.allocate
foo.initialize(bar)
With this:
foo = Foo.new(bar)
It is important to note that there is nothing special about any of these methods. Well, with one exception: Class#allocate obviously has to be able to set the class pointer and to allocate memory, which is something that is not possible in Ruby. So, this method has to somehow come from outside the system, which e.g. in MRI means that it is written in C, not Ruby. But that only concerns the implementation. There are no special dispatch rules, no special override rules. It's just a method like any other that can e.g. call super whereever, whenever and how often it wants and can return what it wants.
"Special" is the magic word here. There's absolutely nothing wrong with calling a constructor a special method, but what "special" implies can vary depending on the language.
In most cases, "special" means they can't return values or be called as a method without creating a new object. But there are always exceptions: a prime example is JavaScript, where a constructor is no different from a normal function, it can return its own values and it can be called either as a constructor or as a simple function.
At least in vb.net, constructors can have a non-standard control flow. If the first statement of a constructor is a call to New (of either the same type or a base type), the sequence of events will be: (1) perform the call; (2) initialize all the fields associated with the type; (3) finish handling the rest of the constructor. No normal method has that sort of control flow. This control flow makes it possible to do things like pass constructor parameters to field initializers of a derived type, if the base type is written to allow such.
#Tom Brito, personally I would agree with you that a constructor is a special case of method.
Also, see below:
A constructor in a class is a special type of subroutine called at the creation of an object.
... A constructor resembles an instance method, but it differs from a method in that it never has an explicit return-type...
Source:
Wikipedia
Also, you may read my comments on others' comment (woot4moo, phunehehe).
Related
Currently we are writing our bachelor thesis about the implementation of a Compiler for an academic object-oriented mini programming language.
We want to be precise in our documentation, and we're currently discussing if a constructor is a routine.
What we think points out that a constructor is a routine is that it has a block of Commands, Parameters and local variables. Despite the missing name, all other attributes of other routines are given.
What we think points out that a constructor is not a routine is that it can only be called once per instance.
We are not sure if this question has a clear answer, or if the definition is different from theory to theory.
We would be happy if someone could give a pointer to some literature about this semantic question.
Best
Edit: Some Information about how we name specific things in our Language:
We have functions and procedures. Functions do have a return value, procedures don't.
A constructor is like an unnamed procedure (without explicit return value)
a constructor is called implicit, java like: x := new X(1, new Y())
Parameters are defined during the definition of a constructor. The own instance (this) is not considered a parameter but provided implicitly
Thanks for your answers so far, they're helping with the though process.
This depends on language - and for this academic language - I would not say that a constructor is a routine. I say that because in not saying that it is a routine, a separation is kept: unless the language explicitly unifies routines/functions/constructors, don't say it does :)
Now, consider these counter-examples (and there are many more, I am sure):
Languages like Eiffel allow giving constructors different names (which I think is awesome and wish was used more).
Languages like Ruby don't have a "new" operator and invoking a constructor appears as invoking any (class) method. Ruby doesn't even have a way of signaling that a method acts as a constructor (or factory method, as it were).
Constructors in languages like JavaScript are just functions which can be run in a special context when used with new.
Also, at some level it may be viewed that there needs to be no difference in calling a constructor multiple times (you get back a new object - so what?) than calling a function multiple times (where one might get back the same value). Consider that the new object may be immutable and may have value equality with other objects.
That is, considering the following code, is there a constructor used?
5 4 vec2 "1" int 2 vec2 add puts
I made it up, but I hope it makes a point. There may or may not be a constructor or an external difference between a constructor and an ordinary function depending upon how the specific language views the role (or even need) of constructors.
Now, write the language specification as deemed fit and try to avoid leaking implementation details.
Constructor is a constructor.
It may be like a function(that returns value: the new object), procedure(routine, function with no return value, called on uninitialized object), it may be callable once or many times on an object (although it is arguable whever the object is of the same identity afterwards..), it may have a name or not or the name may be enforced to match the class, etc. The constructor may even "not exist" or be implicitly created by the compiler from various scattered initializers and code blocks, which otherwise would be expressions/routines/whatchamacallit.
It all depends on your language that you compile and on what do you mean by 'function', 'routine', or even 'parameters' (i.e. is 'this' a parameter?).
If you want to ask about such thing, first describe/define your language and all your terms that you want to use (what is a class? method? function? routine? parameter? constructor? ...) and then, well, most probably you will automatically deduce the answer matching your ontology.
A constructor is a function with special semantics (such that it is called in specific context - as part of object construction), but it is a function anyway - it can have parameters, it has usual flow of control, it can have local variables, etc. It is not better or worse than any other function. I'd say it is a routine.
From outside, a constructor can be seen as a class method, with an instance of that class as return value. Insofar, the claim that "it can only be used once per instance" does not hold water, since there is no instance yet when the constructor is used.
From inside, some special keywordish name like "this" is bound to the uninitialized instance.
Usually, there is some syntactic sugar, like a new keyword. Also, the compiler may help to make sure the instance is properly initialized.
It is special insofar as the functionality of creating a new object is nowhere else provided. But as far as its usage is concerned, a constructor is not (or at least should not be) different from any other class method that happens to return an instance of the class.
BTW, is "routine" an established term in OOP?
I think that a Routine is what is that can be called explicitly as and when required by the caller on a constructed object/class, while a constructor can be called a special type of routine that is called at runtime when the instance of the class is requested.
A constructor helps only in constructing and initializing the class
object and its variables.
It may or may not accept parameters, it can be overloaded with
different set of parameters
If the constructor has no parameters and also no code inside its code
block, you may want to omit it
Some languages automatically create a default parameter-less
constructor (like C#) if you do not provide your own constructor
A constructor can have an access modifier to restrict the creation
scope of the class
A constructor cannot have a return type because its constructing the
same class in which it is declared, and obviously there is no point
returning the same type (may be that's the reason some languages use same name for the constructor as the class name)
All the implementation rules for a constructor differ from language to language
Furthermore, the most important requirement of a well written constructor is that after it is executed it should leave the class object in a valid state
A constructor (as in the name) is only executed by the compiler when you create a new instance of that class.
The general idea is this: You put some set of operations which should be executed during the startup and that is what is done on the constructor. So this implies, you cannot call a constructor just like the other methods of your class.
I'm trying to understand whether the answer to the following question is the same in all major OOP languages; and if not, then how do those languages differ.
Suppose I have class A that defines methods act and jump; method act calls method jump. A's subclass B overrides method jump (i.e., the appropriate syntax is used to ensure that whenever jump is called, the implementation in class B is used).
I have object b of class B. I want it to behave exactly as if it was of class A. In other words, I want the jump to be performed using the implementation in A. What are my options in different languages?
For example, can I achieve this with some form of downcasting? Or perhaps by creating a proxy object that knows which methods to call?
I would want to avoid creating a brand new object of class A and carefully setting up the sharing of internal state between a and b because that's obviously not future-proof, and complicated. I would also want to avoid copying the state of b into a brand new object of class A because there might be a lot of data to copy.
UPDATE
I asked this question specifically about Python, but it seems this is impossible to achieve in Python and technically it can be done... kinda..
It appears that apart from technical feasibility, there's a strong argument against doing this from a design perspective. I'm asking about that in a separate question.
The comments reiterated: Prefer composition over inheritance.
Inheritance works well when your subclasses have well defined behavioural differences from their superclass, but you'll frequently hit a point where that model gets awkward or stops making sense. At that point, you need to reconsider your design.
Composition is usually the better solution. Delegating your object's varying behaviour to a different object (or objects) may reduce or eliminate your need for subclassing.
In your case, the behavioural differences between class A and class B could be encapsulated in the Strategy pattern. You could then change the behaviour of class A (and class B, if still required) at the instance level, simply by assigning a new strategy.
The Strategy pattern may require more code in the short run, but it's clean and maintainable. Method swizzling, monkey patching, and all those cool things that allow us to poke around in our specific language implementation are fun, but the potential for unexpected side effects is high and the code tends to be difficult to maintain.
What you are asking is completely unrelated/unsupported by OOP programming.
If you subclass an object A with class B and override its methods, when a concrete instance of B is created then all the overriden/new implementation of the base methods are associated with it (either we talk about Java or C++ with virtual tables etc).
You have instantiated object B.
Why would you expect that you could/would/should be able to call the method of the superclass if you have overriden that method?
You could call it explicitely of course e.g. by calling super inside the method, but you can not do it automatically, and casting will not help you do that either.
I can't imagine why you would want to do that.
If you need to use class A then use class A.
If you need to override its functionality then use its subclass B.
Most programming languages go to some trouble to support dynamic dispatch of virtual functions (the case of calling the overridden method jump in a subclass instead of the parent class's implementation) -- to the degree that working around it or avoiding it is difficult. In general, specialization/polymorphism is a desirable feature -- arguably a goal of OOP in the first place.
Take a look at the Wikipedia article on Virtual Functions, which gives a useful overview of the support for virtual functions in many programming languages. It will give you a place to start when considering a specific language, as well as the trade-offs to weigh when looking at a language where the programmer can control how dispatch behaves (see the section on C++, for example).
So loosely, the answer to your question is, "No, the behavior is not the same in all programming languages." Furthermore, there is no language independent solution. C++ may be your best bet if you need the behavior.
You can actually do this with Python (sort of), with some awful hacks. It requires that you implement something like the wrappers we were discussing in your first Python-specific question, but as a subclass of B. You then need to implement write-proxying as well (the wrapper object shouldn't contain any of the state normally associated with the class hierarchy, it should redirect all attribute access to the underlying instance of B.
But rather than redirecting method lookup to A and then calling the method with the wrapped instance, you'd call the method passing the wrapper object as self. This is legal because the wrapper class is a subclass of B, so the wrapper instance is an instance of the classes whose methods you're calling.
This would be very strange code, requiring you to dynamically generate classes using both IS-A and HAS-A relationships at the same time. It would probably also end up fairly fragile and have bizarre results in a lot of corner cases (you generally can't write 100% perfect wrapper classes in Python exactly because this sort of strange thing is possible).
I'm completely leaving aside weather this is a good idea or not.
I often need to decide between these two strategies for the object design:
An object that is fully initialised and ready to use after its construction. The constructor often requires a complex list of parameters, hence the object initialisation is nontrivial. All objects having it as a member variable will also need nontrivial constructors. This may lead to code whose complexity is concentrated at object constructors, often making the code hard to follow.
An object with default constructor. The object variables are set individually by means of setter methods. This approach has the disadvantage that most methods need to check whether the object is fully initialized, hence complicating the code.
What is your personal preference between the two, and how do you decide when to use one or the other?
In my opinion if a constructor is getting too bloated it's time to split up your object in more different, smaller objects. This might be impossible in some rare cases, but in most cases it can be done.
Neither.
Huge parameter lists indicates the object does too much. Lots of properties that need to be set before the object can have a valid and useful output indicates it does too much.
So neither approach is a solution as far as I'm concerned.
There are lots of ways to break these things up, but outside of a specific scenario, the only rule is, "It needs doing".
Aggregation into other objects, "controller" classes, various communicator patterns. Are some categories first class objects, can some be hidden in the implementation.
I don't accept that the two options you present are the only ones, except possibly from a pragmatic point of view in terms of getting the code out of the door. Which one I was then forced to choose, would simply depend on how many calls to the constructor with different parameters the code required, versus how much validation would be needed to confirm all the properties were set, and possibly the impact on unit tests, which because the object is a mess would be unwieldy or limited.
If a constructor takes many arguments — you call this non-trivial object initialisation — and you don't want to split up your class into smaller ones, then one alternative is to put the parameters into a Parameter Object and then only pass that object to the constructor.
Second, I believe that you should distinguish between...
object properties that absolutely must be set if the object is supposed to do its work, and there is no sensible default value. These properties should be initialised via a constructor parameter.
object properties that can be set optionally, or overridden, by the user. While you might initialise such properties in the constructor, you don't have to have a separate constructor parameter for them. Instead, you might assign a sensible default value to them that still can be overridden by the user through a setter method.
There is also an alternative to the first type of properties (those that must absolutely have a user-provided value): properties which are provided through overriding an abstract getter in a derived class:
abstract class ComplicatedFoo {
protected abstract T getSomeDependency(); // replaces required ctor parameter
}
P.S.: The book "Dependency Injection" by Dhanji R. Prasanna (Manning Publications) gives a good overview of the various ways how to initialise an object.
It's always good to initialize all your variables in the constructor, but to a default value. If it is difficult to get the value of the variable (for example, you have to call some function somewhere to get that value), you may set that value to an invalid one and then later you set the correct value.
It is not a good idea to make the constructor so complex, because you can't return an error in the constructor (I don't know if it is ok to throw an exception in the constructor or not, because I particulary don't like trhowing exceptions anywhere). Also, you can't call virtual functions there, and so on.
An approach I like when the construction of the class is complex is to create an "init" function. Then I can do something like:
Person::Person()
{
age = -1;
...
}
int Person::Init()
{
age = functionThatReturnsTheAgeFromSomeDB();
if (age == -1 )
{
return DB_ERROR;
}
...
}
And so on.
I have some questions about the affects of using concrete classes and interfaces.
Say some chunk of code (call it chunkCode) uses concrete class A. Would I have to re-compile chunkCode if:
I add some new public methods to A? If so, isn't that a bit stange? After all I still provide the interface chunkCode relies on. (Or do I have to re-compile because chunkCode may never know otherwise that this is true and I haven't omitted some API)
I add some new private methods to A?
I add a new public field to A?
I add a new private field to A?
Factory Design Pattern:
The main code doesn't care what the concrete type of the object is. It relies only on the API. But what would you do if there are few methods which are relevant to only one concrete type? This type implements the interface but adds some more public methods? Would you use some if (A is type1) statements (or the like) the main code?
Thanks for any clarification
1) Compiling is not an activity in OO. It is a detail of specific OO implementations. If you want an answer for a specific implementation (e.g. Java), then you need to clarify.
In general, some would say that adding to an interface is not considered a breaking change, wheras others say you cannot change an interface once it is published, and you have to create a new interface.
Edit: You specified C#, so check out this question regarding breaking changes in .Net. I don't want to do that answer a disservice, so I won't try to replicate it here.
2) People often hack their designs to do this, but it is a sign that you have a poor design.
Good alternatives:
Create a method in your interface that allows you to invoke the custom behavior, but not be required to know what that behavior is.
Create an additional interface (and a new factory) that supports the new methods. The new interface does not have to inherit the old interface, but it can if it makes sense (if an is-a relationship can be expressed between the interfaces).
If your language supports it, use the Abstract Factory pattern, and take advantage of Covariant Return Types in the concrete factory. If you need a specific derived type, accept a concrete factory instead of an abstract one.
Bad alternatives (anti-patterns):
Adding a method to the interface that does nothing in other derived classed.
Throwing an exception in a method that doesn't make sense for your derived class.
Adding query methods to the interface that tell the user if they can call a certain method.
Unless the method name is generic enough that the user wouldn't expect it to do anything (e.g. DoExtraProcessing), then adding a method that is no-op in most derived classes breaks the contract defined by that interface.
E.g.: Someone invoking bird.Fly() would expect it to actually do something. We know that chickens can't fly. So either a Chicken isn't a Bird, or Birds don't Fly.
Adding query methods is a poor work-around for this. E.g. Adding a boolean CanFly() method or property in your interface. So is throwing an exception. Neither of them get around the fact that the type simply isn't substitutable. Check out the Liskov Substitution Principle (LSP).
For your first question the answer is NO for all your points. If it would be that way then backward compatibility would not make any sense. You have to recompile chunkCode only if you brake the API, that is remove some functionality that chunkCode is using, changing calling conventions, modifying number of parameters, these sort of things == breaking changes.
For the second I usually, but only if I really have to, use dynamic_cast in those situations.
Note my answer is valid in the context of C++;I just saw the question is language agnostic(kind of tired at this hour; I'll remove the answer if it offenses anybody).
Question 1: Depends on what language you are talking about. Its always safer to recompile both languages though. Mostly because chuckCode does not know what actually exists inside A. Recompiling refreshes its memory. But it should work in Java without recompiling.
Question 2: No. The entire point of writing a Factory is to get rid of if(A is type1). These if statements are terrible from maintenance perspective.
Factory is designed to build objects of similar type. If you are having a situation where you are using this statement then that object is either not a similar type to rest of the classes. If you are sure it is of similar type and have similar interfaces. I would write an extra function in all the concrete base classes and implement it only on this one.
Ideally All these concrete classes should have a common abstract base class or a Interface to define what the API is. Nothing other than what is designed in this Interface should be expected to be called anywhere in the code unless you are writing functions that takes this specific class.
In my design I am using objects that evaluate a data record. The constructor is called with the data record and type of evaluation as parameters and then the constructor calls all of the object's code necessary to evaluate the record. This includes using the type of evaluation to find additional parameter-like data in a text file.
There are in the neighborhood of 250 unique evaluation types that use the same or similar code and unique parameters coming from the text file.
Some of these evaluations use different code so I benefit a lot from this model because I can use inheritance and polymorphism.
Once the object is created there isn't any need to execute additional code on the object (at least for now) and it is used more like a struct; its kept on a list and 3 properties are used later.
I think this design is the easiest to understand, code, and read.
A logical alternative I guess would be using functions that return score structs, but you can't inherit from methods so it would make it kind of sloppy imo.
I am using vb.net and these classes will be used in an asp.net web app as well as in a distributed app.
thanks for your input
Executing code in a constructor is OK; but having only properties with no methods might be a violation of the tell don't ask principle: perhaps instead those properties should be private, and the code which uses ("asks") those properties should become methods of the class (which you can invoke or "tell").
In general, putting code that does anything significant in the constructor a not such a good idea, because you'll eventually get hamstrung on the rigid constructor execution order when you subclass.
Constructors are best used for getting your object to a consistent state. "Real" work is best handled in instance methods. With the work implemented as a method, you gain:
separation of what you want to evaluate from when you want to evaluate it.
polymorphism (if using virtual methods)
the option to split up the work into logical pieces, implementing each piece as a concrete template method. These template methods can be overridden in subclasses, which provides for "do it mostly like my superclass, but do this bit differently".
In short, I'd use methods to implement the main computation. If you're concerned that an object will be created without it's evaluation method being called, you can use a factory to create the objects, which calls the evaluate method after construction. You get the safety of constructors, with the execution order flexibility of methods.