Is it good convention for a class to perform functions on itself? - oop

I've always been taught that if you are doing something to an object, that should be an external thing, so one would Save(Class) rather than having the object save itself: Class.Save().
I've noticed that in the .Net libraries, it is common to have a class modify itself as with String.Format() or sort itself as with List.Sort().
My question is, in strict OOP is it appropriate to have a class which performs functions on itself when called to do so, or should such functions be external and called on an object of the class' type?

Great question. I have just recently reflected on a very similar issue and was eventually going to ask much the same thing here on SO.
In OOP textbooks, you sometimes see examples such as Dog.Bark(), or Person.SayHello(). I have come to the conclusion that those are bad examples. When you call those methods, you make a dog bark, or a person say hello. However, in the real world, you couldn't do this; a dog decides himself when it's going to bark. A person decides itself when it will say hello to someone. Therefore, these methods would more appropriately be modelled as events (where supported by the programming language).
You would e.g. have a function Attack(Dog), PlayWith(Dog), or Greet(Person) which would trigger the appropriate events.
Attack(dog) // triggers the Dog.Bark event
Greet(johnDoe) // triggers the Person.SaysHello event
As soon as you have more than one parameter, it won't be so easy deciding how to best write the code. Let's say I want to store a new item, say an integer, into a collection. There's many ways to formulate this; for example:
StoreInto(1, collection) // the "classic" procedural approach
1.StoreInto(collection) // possible in .NET with extension methods
Store(1).Into(collection) // possible by using state-keeping temporary objects
According to the thinking laid out above, the last variant would be the preferred one, because it doesn't force an object (the 1) to do something to itself. However, if you follow that programming style, it will soon become clear that this fluent interface-like code is quite verbose, and while it's easy to read, it can be tiring to write or even hard to remember the exact syntax.
P.S.: Concerning global functions: In the case of .NET (which you mentioned in your question), you don't have much choice, since the .NET languages do not provide for global functions. I think these would be technically possible with the CLI, but the languages disallow that feature. F# has global functions, but they can only be used from C# or VB.NET when they are packed into a module. I believe Java also doesn't have global functions.
I have come across scenarios where this lack is a pity (e.g. with fluent interface implementations). But generally, we're probably better off without global functions, as some developers might always fall back into old habits, and leave a procedural codebase for an OOP developer to maintain. Yikes.
Btw., in VB.NET, however, you can mimick global functions by using modules. Example:
Globals.vb:
Module Globals
Public Sub Save(ByVal obj As SomeClass)
...
End Sub
End Module
Demo.vb:
Imports Globals
...
Dim obj As SomeClass = ...
Save(obj)

I guess the answer is "It Depends"... for Persistence of an object I would side with having that behavior defined within a separate repository object. So with your Save() example I might have this:
repository.Save(class)
However with an Airplane object you may want the class to know how to fly with a method like so:
airplane.Fly()
This is one of the examples I've seen from Fowler about an aenemic data model. I don't think in this case you would want to have a separate service like this:
new airplaneService().Fly(airplane)
With static methods and extension methods it makes a ton of sense like in your List.Sort() example. So it depends on your usage pattens. You wouldn't want to have to new up an instance of a ListSorter class just to be able to sort a list like this:
new listSorter().Sort(list)

In strict OOP (Smalltalk or Ruby), all methods belong to an instance object or a class object. In "real" OOP (like C++ or C#), you will have static methods that essentially stand completely on their own.
Going back to strict OOP, I'm more familiar with Ruby, and Ruby has several "pairs" of methods that either return a modified copy or return the object in place -- a method ending with a ! indicates that the message modifies its receiver. For instance:
>> s = 'hello'
=> "hello"
>> s.reverse
=> "olleh"
>> s
=> "hello"
>> s.reverse!
=> "olleh"
>> s
=> "olleh"
The key is to find some middle ground between pure OOP and pure procedural that works for what you need to do. A Class should do only one thing (and do it well). Most of the time, that won't include saving itself to disk, but that doesn't mean Class shouldn't know how to serialize itself to a stream, for instance.

I'm not sure what distinction you seem to be drawing when you say "doing something to an object". In many if not most cases, the class itself is the best place to define its operations, as under "strict OOP" it is the only code that has access to internal state on which those operations depend (information hiding, encapsulation, ...).
That said, if you have an operation which applies to several otherwise unrelated types, then it might make sense for each type to expose an interface which lets the operation do most of the work in a more or less standard way. To tie it in to your example, several classes might implement an interface ISaveable which exposes a Save method on each. Individual Save methods take advantage of their access to internal class state, but given a collection of ISaveable instances, some external code could define an operation for saving them to a custom store of some kind without having to know the messy details.

It depends on what information is needed to do the work. If the work is unrelated to the class (mostly equivalently, can be made to work on virtually any class with a common interface), for example, std::sort, then make it a free function. If it must know the internals, make it a member function.
Edit: Another important consideration is performance. In-place sorting, for example, can be miles faster than returning a new, sorted, copy. This is why quicksort is faster than merge sort in the vast majority of cases, even though merge sort is theoretically faster, which is because quicksort can be performed in-place, whereas I've never heard of an in-place merge-sort. Just because it's technically possible to perform an operation within the class's public interface, doesn't mean that you actually should.

Related

Is Polymorphism a waste to apply for the classes that we exactly know the type prior run-time?

Run-time Polymorphism can be used to let the run-time to dynamically load the exact concrete class of an abstract class/interface. (You can take Animal/Dog, Vehicle/Car examples)
But when we know the exact concrete class #coding-time (compile-time), does it really need to forcefully apply polymorphism?
When I write OO code, I tend to use most-general type I can on the left-hand side of the assignment. This immediately means that my answer to your question is - no.
Here's the example:
Animal x = new Dog();
...
x.move();
The reason why I'm doing this is that I'm probably going to split beginning and end of the operation into two distinct operations. My methods are extremely short in practice.
Applied to the same example:
function moveDog() {
move(new Dog());
}
function move(Animal animal) {
animal.move();
}
As you can see, it would make no sense for the move function to know what kind of animal it is really moving.
Generally, it is compiler's duty to figure whether in a given code base any concrete call has been made with an overridden move() method. Some compilers can detect that no overridden method will be subjected to them and then they remove dynamic dispatch at compile time. With some luck, my code above would compile the same whether move function receives Animal or Dog.
Now, this is theory. In practice, there are two important things. First, compilers that are widely used have still not started using such aggressive optimization techniques as detecting static method calls, as opposed to calls that require dynamic dispatch. Second, the first thing doesn't matter too much with CPU power we have today.
I have been writing highly optimized code for fifteen years already and I have met the situation in which I had to factor polymorphic calls out. That is why I strongly recommend to apply polymorphism as much as possible. When the time comes to add some classes, to incorporate new features, polymorphic calls will likely be the tool to seamlessly add new classes to the existing design. If you used overly concrete types during development, it could easily happen that you cannot add new feature to the given code base.
But when we know the exact concrete class #coding-time (compile-time), does it really need to forcefully apply polymorphism?
Knowing the type at compile time is not necessarily a yes/no thing across all the code in an app and an object's entire lifetime, given techniques for type erasure. But, ignoring those classic uses of polymorphism, there are still other potential reasons such as...
(sorry - pretty obvious one this) to make it easier to change the implementation should another become available later
to make it easier to "mock" an implementation for testing (i.e. provide objects that pretend to provide some service or function, but have more scripted/controllable/observable behaviours to let tests put some dependent code through its paces)
hide aspects of the implementation that might otherwise have to be exposed (e.g. in C++, a class/struct definition must declare all the protected and private members)
this is sometimes for Intellectual Property protection; at other times, so more changes can be made to the implementation without having to make a change the "header" file that would typically trigger recompilation of a lot of dependent code
to aid in modelling and application design, using the "interfaces" to cleanly specify the intended APIs, which can then provide a more stable reference for comparison as the implementations are fleshed out

can overriding of a method be prevented by downcasting to a superclass?

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.

Why would I want to use Interfaces? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
I understand that they force you to implement methods and such but what I cant understand is why you would want to use them. Can anybody give me a good example or explanation on why I would want to implement this.
One specific example: interfaces are a good way of specifying a contract that other people's code must meet.
If I'm writing a library of code, I may write code that is valid for objects that have a certain set of behaviours. The best solution is to specify those behaviours in an interface (no implementation, just a description) and then use references to objects implementing that interface in my library code.
Then any random person can come along, create a class that implements that interface, instantiate an object of that class and pass it to my library code and expect it to work. Note: it is of course possible to strictly implement an interface while ignoring the intention of the interface, so merely implementing an interface is no guarantee that things will work. Stupid always finds a way! :-)
Another specific example: two teams working on different components that must co-operate. If the two teams sit down on day 1 and agree on a set of interfaces, then they can go their separate ways and implement their components around those interfaces. Team A can build test harnesses that simulate the component from Team B for testing, and vice versa. Parallel development, and fewer bugs.
The key point is that interfaces provide a layer of abstraction so that you can write code that is ignorant of unnecessary details.
The canonical example used in most textbooks is that of sorting routines. You can sort any class of objects so long as you have a way of comparing any two of the objects. You can make any class sortable therefore by implementing the IComparable interface, which forces you to implement a method for comparing two instances. All of the sort routines are written to handle references to IComparable objects, so as soon as you implement IComparable you can use any of those sort routines on collections of objects of your class.
The easiest way of understanding interfaces is that they allow different objects to expose COMMON functionality. This allows the programmer to write much simplier, shorter code that programs to an interface, then as long as the objects implement that interface it will work.
Example 1:
There are many different database providers, MySQL, MSSQL, Oracle, etc. However all database objects can DO the same things so you will find many interfaces for database objects. If an object implements IDBConnection then it exposes the methods Open() and Close(). So if I want my program to be database provider agnostic, I program to the interface and not to the specific providers.
IDbConnection connection = GetDatabaseConnectionFromConfig()
connection.Open()
// do stuff
connection.Close()
See by programming to an interface (IDbconnection) I can now SWAP out any data provider in my config but my code stays the exact same. This flexibility can be extremely useful and easy to maintain. The downside to this is that I can only perform 'generic' database operations and may not fully utilize the strength that each particular provider offers so as with everything in programming you have a trade off and you must determine which scenario will benefit you the most.
Example 2:
If you notice almost all collections implement this interface called IEnumerable. IEnumerable returns an IEnumerator which has MoveNext(), Current, and Reset(). This allows C# to easily move through your collection. The reason it can do this is since it exposes the IEnumerable interface it KNOWS that the object exposes the methods it needs to go through it. This does two things. 1) foreach loops will now know how to enumerate the collection and 2) you can now apply powerful LINQ exprssions to your collection. Again the reason why interfaces are so useful here is because all collections have something in COMMON, they can be moved through. Each collection may be moved through a different way (linked list vs array) but that is the beauty of interfaces is that the implementation is hidden and irrelevant to the consumer of the interface. MoveNext() gives you the next item in the collection, it doesn't matter HOW it does it. Pretty nice, huh?
Example 3:
When you are designing your own interfaces you just have to ask yourself one question. What do these things have in common? Once you find all the things that the objects share, you abstract those properties/methods into an interface so that each object can inherit from it. Then you can program against several objects using one interface.
And of course I have to give my favorite C++ polymorphic example, the animals example. All animals share certain characteristics. Lets say they can Move, Speak, and they all have a Name. Since I just identified what all my animals have in common and I can abstract those qualities into the IAnimal interface. Then I create a Bear object, an Owl object, and a Snake object all implementing this interface. The reason why you can store different objects together that implement the same interface is because interfaces represent an IS-A replationship. A bear IS-A animal, an owl IS-A animal, so it makes since that I can collect them all as Animals.
var animals = new IAnimal[] = {new Bear(), new Owl(), new Snake()} // here I can collect different objects in a single collection because they inherit from the same interface
foreach (IAnimal animal in animals)
{
Console.WriteLine(animal.Name)
animal.Speak() // a bear growls, a owl hoots, and a snake hisses
animal.Move() // bear runs, owl flys, snake slithers
}
You can see that even though these animals perform each action in a different way, I can program against them all in one unified model and this is just one of the many benefits of Interfaces.
So again the most important thing with interfaces is what do objects have in common so that you can program against DIFFERENT objects in the SAME way. Saves time, creates more flexible applications, hides complexity/implementation, models real-world objects / situations, among many other benefits.
Hope this helps.
One typical example is a plugin architecture. Developer A writes the main app, and wants to make certain that all plugins written by developer B, C and D conform to what his app expects of them.
Interfaces define contracts, and that's the key word.
You use an interface when you need to define a contract in your program but you don't really care about the rest of the properties of the class that fulfills that contract as long as it does.
So, let's see an example. Suppose you have a method which provides the functionality to sort a list. First thing .. what's a list? Do you really care what elements does it holds in order to sort the list? Your answer should be no... In .NET (for example) you have an interface called IList which defines the operations that a list MUST support so you don't care the actual details underneath the surface.
Back to the example, you don't really know the class of the objects in the list... neither you care. If you can just compare the object you might as well sort them. So you declare a contract:
interface IComparable
{
// Return -1 if this is less than CompareWith
// Return 0 if object are equal
// Return 1 if CompareWith is less than this
int Compare(object CompareWith);
}
that contract specify that a method which accepts an object and returns an int must be implemented in order to be comparable. Now you have defined an contract and for now on you don't care about the object itself but about the contract so you can just do:
IComparable comp1 = list.GetItem(i) as IComparable;
if (comp1.Compare(list.GetItem(i+1)) < 0)
swapItem(list,i, i+1)
PS: I know the examples are a bit naive but they are examples ...
When you need different classes to share same methods you use Interfaces.
Interfaces are absolutely necessary in an object-oriented system that expects to make good use of polymorphism.
A classic example might be IVehicle, which has a Move() method. You could have classes Car, Bike and Tank, which implement IVehicle. They can all Move(), and you could write code that didn't care what kind of vehicle it was dealing with, just so it can Move().
void MoveAVehicle(IVehicle vehicle)
{
vehicle.Move();
}
The pedals on a car implement an interface. I'm from the US where we drive on the right side of the road. Our steering wheels are on the left side of the car. The pedals for a manual transmission from left to right are clutch -> brake -> accelerator. When I went to Ireland, the driving is reversed. Cars' steering wheels are on the right and they drive on the left side of the road... but the pedals, ah the pedals... they implemented the same interface... all three pedals were in the same order... so even if the class was different and the network that class operated on was different, i was still comfortable with the pedal interface. My brain was able to call my muscles on this car just like every other car.
Think of the numerous non-programming interfaces we can't live without. Then answer your own question.
Imagine the following basic interface which defines a basic CRUD mechanism:
interface Storable {
function create($data);
function read($id);
function update($data, $id);
function delete($id);
}
From this interface, you can tell that any object that implements it, must have functionality to create, read, update and delete data. This could by a database connection, a CSV file reader, and XML file reader, or any other kind of mechanism that might want to use CRUD operations.
Thus, you could now have something like the following:
class Logger {
Storable storage;
function Logger(Storable storage) {
this.storage = storage;
}
function writeLogEntry() {
this.storage.create("I am a log entry");
}
}
This logger doesn't care if you pass in a database connection, or something that manipulates files on disk. All it needs to know is that it can call create() on it, and it'll work as expected.
The next question to arise from this then is, if databases and CSV files, etc, can all store data, shouldn't they be inherited from a generic Storable object and thus do away with the need for interfaces? The answer to this is no... not every database connection might implement CRUD operations, and the same applies to every file reader.
Interfaces define what the object is capable of doing and how you need to use it... not what it is!
Interfaces are a form of polymorphism. An example:
Suppose you want to write some logging code. The logging is going to go somewhere (maybe to a file, or a serial port on the device the main code runs on, or to a socket, or thrown away like /dev/null). You don't know where: the user of your logging code needs to be free to determine that. In fact, your logging code doesn't care. It just wants something it can write bytes to.
So, you invent an interface called "something you can write bytes to". The logging code is given an instance of this interface (perhaps at runtime, perhaps it's configured at compile time. It's still polymorphism, just different kinds). You write one or more classes implementing the interface, and you can easily change where logging goes just by changing which one the logging code will use. Someone else can change where logging goes by writing their own implementations of the interface, without changing your code. That's basically what polymorphism amounts to - knowing just enough about an object to use it in a particular way, while allowing it to vary in all the respects you don't need to know about. An interface describes things you need to know.
C's file descriptors are basically an interface "something I can read and/or write bytes from and/or to", and almost every typed language has such interfaces lurking in its standard libraries: streams or whatever. Untyped languages usually have informal types (perhaps called contracts) that represent streams. So in practice you almost never have to actually invent this particular interface yourself: you use what the language gives you.
Logging and streams are just one example - interfaces happen whenever you can describe in abstract terms what an object is supposed to do, but don't want to tie it down to a particular implementation/class/whatever.
There are a number of reasons to do so. When you use an interface, you're ready in the future when you need to refactor/rewrite the code. You can also provide an sort of standardized API for simple operations.
For example, if you want to write a sort algorithm like the quicksort, all you need to sort any list of objects is that you can successfuuly compare two of the objects. If you create an interface, say ISortable, than anyone who creates objects can implement the ISortable interface and they can use your sort code.
If you're writing code that uses a database storage, and you write to an storage interface, you can replace that code down the line.
Interfaces encourage looser coupling of your code so that you can have greater flexibility.
In an article in my blog I briefly describe three purposes interfaces have.
Interfaces may have different
purposes:
Provide different implementations for the same goal. The typical example
is a list, which may have different
implementations for different
performance use cases (LinkedList,
ArrayList, etc.).
Allow criteria modification. For example, a sort function may accept a
Comparable interface in order to
provide any kind of sort criteria,
based on the same algorithm.
Hide implementation details. This also makes it easier for a user to
read the comments, since in the body
of the interface there are only
methods, fields and comments, no long
chunks of code to skip.
Here's the article's full text: http://weblogs.manas.com.ar/ary/2007/11/
The best Java code I have ever seen defined almost all object references as instances of interfaces instead of instances of classes. It is a strong sign of quality code designed for flexibility and change.
As you noted, interfaces are good for when you want to force someone to make it in a certain format.
Interfaces are good when data not being in a certain format can mean making dangerous assumptions in your code.
For example, at the moment I'm writing an application that will transform data from one format in to another. I want to force them to place those fields in so I know they will exist and will have a greater chance of being properly implemented. I don't care if another version comes out and it doesn't compile for them because it's more likely that data is required anyways.
Interfaces are rarely used because of this, since usually you can make assumptions or don't really require the data to do what you need to do.
An interface, defines merely the interface. Later, you can define method (on other classes), which accepted interfaces as parameters (or more accurately, object which implement that interface). This way your method can operate on a large variety of objects, whose only commonality is that they implement that interface.
First, they give you an additional layer of abstraction. You can say "For this function, this parameter must be an object that has these methods with these parameters". And you probably want to also set the meaning of these methods, in somehow abstracted terms, yet allowing you to reason about the code. In duck-typed languages you get that for free. No need for explicit, syntax "interfaces". Yet you probably still create a set of conceptual interfaces, something like contracts (like in Design by Contract).
Furthermore, interfaces are sometimes used for less "pure" purposes. In Java, they can be used to emulate multiple inheritance. In C++, you can use them to reduce compile times.
In general, they reduce coupling in your code. That's a good thing.
Your code may also be easier to test this way.
Let's say you want to keep track of a collection of stuff. Said collections must support a bunch of things, like adding and removing items, and checking if an item is in the collection.
You could then specify an interface ICollection with the methods add(), remove() and contains().
Code that doesn't need to know what kind of collection (List, Array, Hash-table, Red-black tree, etc) could accept objects that implemented the interface and work with them without knowing their actual type.
In .Net, I create base classes and inherit from them when the classes are somehow related. For example, base class Person could be inherited by Employee and Customer. Person might have common properties like address fields, name, telephone, and so forth. Employee might have its own department property. Customer has other exclusive properties.
Since a class can only inherit from one other class in .Net, I use interfaces for additional shared functionality. Sometimes interfaces are shared by classes that are otherwise unrelated. Using an interface creates a contract that developers will know is shared by all of the other classes implementing it. I also forces those classes to implement all of its members.
In C# interfaces are also extremely useful for allowing polymorphism for classes that do not share the same base classes. Meaning, since we cannot have multiple inheritance you can use interfaces to allow different types to be used. It's also a way to allow you to expose private members for use without reflection (explicit implementation), so it can be a good way to implement functionality while keeping your object model clean.
For example:
public interface IExample
{
void Foo();
}
public class Example : IExample
{
// explicit implementation syntax
void IExample.Foo() { ... }
}
/* Usage */
Example e = new Example();
e.Foo(); // error, Foo does not exist
((IExample)e).Foo(); // success
I think you need to get a good understand of design patterns so see there power.
Check out
Head First Design Patterns

What do you call a method of an object that changes its class?

Let's say you have a Person object and it has a method on it, promote(), that transforms it into a Captain object. What do you call this type of method/interaction?
It also feels like an inversion of:
myCaptain = new Captain(myPerson);
Edit: Thanks to all the replies. The reason I'm coming across this pattern (in Perl, but relevant anywhere) is purely for convenience. Without knowing any implementation deals, you could say the Captain class "has a" Person (I realize this may not be the best example, but be assured it isn't a subclass).
Implementation I assumed:
// this definition only matches example A
Person.promote() {
return new Captain(this)
}
personable = new Person;
// A. this is what i'm actually coding
myCaptain = personable.promote();
// B. this is what my original post was implying
personable.promote(); // is magically now a captain?
So, literally, it's just a convenience method for the construction of a Captain. I was merely wondering if this pattern has been seen in the wild and if it had a name. And I guess yeah, it doesn't really change the class so much as it returns a different one. But it theoretically could, since I don't really care about the original.
Ken++, I like how you point out a use case. Sometimes it really would be awesome to change something in place, in say, a memory sensitive environment.
A method of an object shouldn't change its class. You should either have a member which returns a new instance:
myCaptain = myPerson->ToCaptain();
Or use a constructor, as in your example:
myCaptain = new Captain(myPerson);
I would call it a conversion, or even a cast, depending on how you use the object. If you have a value object:
Person person;
You can use the constructor method to implicitly cast:
Captain captain = person;
(This is assuming C++.)
A simpler solution might be making rank a property of person. I don't know your data structure or requirements, but if you need to something that is trying to break the basics of a language its likely that there is a better way to do it.
You might want to consider the "State Pattern", also sometimes called the "Objects for States" pattern. It is defined in the book Design Patterns, but you could easily find a lot about it on Google.
A characteristic of the pattern is that "the object will appear to change its class."
Here are some links:
Objects for States
Pattern: State
Everybody seems to be assuming a C++/Java-like object system, possibly because of the syntax used in the question, but it is quite possible to change the class of an instance at runtime in other languages.
Lisp's CLOS allows changing the class of an instance at any time, and it's a well-defined and efficient transformation. (The terminology and structure is slightly different: methods don't "belong" to classes in CLOS.)
I've never heard a name for this specific type of transformation, though. The function which does this is simply called change-class.
Richard Gabriel seems to call it the "change-class protocol", after Kiczales' AMOP, which formalized as "protocols" many of the internals of CLOS for metaprogramming.
People wonder why you'd want to do this; I see two big advantages over simply creating a new instance:
faster: changing class can be as simple as updating a pointer, and updating any slots that differ; if the classes are very similar, this can be done with no new memory allocations
simpler: if a dozen places already have a reference to the old object, creating a new instance won't change what they point to; if you need to update each one yourself, that could add a lot of complexity for what should be a simple operation (2 words, in Lisp)
That's not to say it's always the right answer, but it's nice to have the ability to do this when you want it. "Change an instance's class" and "make a new instance that's similar to that one" are very different operations, and I like being able to say exactly what I mean.
The first interesting part would be to know: why do you want/need an object changes its class at runtime?
There are various options:
You want it to respond differently to some methods for a given state of the application.
You might want it to have new functionality that the original class don't have.
Others...
Statically typed languages such as Java and C# don't allow this to happen, because the type of the object should be know at compile time.
Other programming languages such as Python and Ruby may allow this ( I don't know for sure, but I know they can add methods at runtime )
For the first option, the answer given by Charlie Flowers is correct, using the state patterns would allow a class behave differently but the object will have the same interface.
For the second option, you would need to change the object type anyway and assign it to a new reference with the extra functionality. So you will need to create another distinct object and you'll end up with two different objects.

Dealing with "global" data structures in an object-oriented world

This is a question with many answers - I am interested in knowing what others consider to be "best practice".
Consider the following situation: you have an object-oriented program that contains one or more data structures that are needed by many different classes. How do you make these data structures accessible?
You can explicitly pass references around, for example, in the constructors. This is the "proper" solution, but it means duplicating parameters and instance variables all over the program. This makes changes or additions to the global data difficult.
You can put all of the data structures inside of a single object, and pass around references to this object. This can either be an object created just for this purpose, or it could be the "main" object of your program. This simplifies the problems of (1), but the data structures may or may not have anything to do with one another, and collecting them together in a single object is pretty arbitrary.
You can make the data structures "static". This lets you reference them directly from other classes, without having to pass around references. This entirely avoids the disadvantages of (1), but is clearly not OO. This also means that there can only ever be a single instance of the program.
When there are a lot of data structures, all required by a lot of classes, I tend to use (2). This is a compromise between OO-purity and practicality. What do other folks do? (For what it's worth, I mostly come from the Java world, but this discussion is applicable to any OO language.)
Global data isn't as bad as many OO purists claim!
After all, when implementing OO classes you've usually using an API to your OS. What the heck is this if it isn't a huge pile of global data and services!
If you use some global stuff in your program, you're merely extending this huge environment your class implementation can already see of the OS with a bit of data that is domain specific to your app.
Passing pointers/references everywhere is often taught in OO courses and books, academically it sounds nice. Pragmatically, it is often the thing to do, but it is misguided to follow this rule blindly and absolutely. For a decent sized program, you can end up with a pile of references being passed all over the place and it can result in completely unnecessary drudgery work.
Globally accessible services/data providers (abstracted away behind a nice interface obviously) are pretty much a must in a decent sized app.
I must really really discourage you from using option 3 - making the data static. I've worked on several projects where the early developers made some core data static, only to later realise they did need to run two copies of the program - and incurred a huge amount of work making the data non-static and carefully putting in references into everything.
So in my experience, if you do 3), you will eventually end up doing 1) at twice the cost.
Go for 1, and be fine-grained about what data structures you reference from each object. Don't use "context objects", just pass in precisely the data needed. Yes, it makes the code more complicated, but on the plus side, it makes it clearer - the fact that a FwurzleDigestionListener is holding a reference to both a Fwurzle and a DigestionTract immediately gives the reader an idea about its purpose.
And by definition, if the data format changes, so will the classes that operate on it, so you have to change them anyway.
You might want to think about altering the requirement that lots of objects need to know about the same data structures. One reason there does not seem to be a clean OO way of sharing data is that sharing data is not very object-oriented.
You will need to look at the specifics of your application but the general idea is to have one object responsible for the shared data which provides services to the other objects based on the data encapsulated in it. However these services should not involve giving other objects the data structures - merely giving other objects the pieces of information they need to meet their responsibilites and performing mutations on the data structures internally.
I tend to use 3) and be very careful about the synchronisation and locking across threads. I agree it is less OO, but then you confess to having global data, which is very un-OO in the first place.
Don't get too hung up on whether you are sticking purely to one programming methodology or another, find a solution which fits your problem. I think there are perfectly valid contexts for singletons (Logging for instance).
I use a combination of having one global object and passing interfaces in via constructors.
From the one main global object (usually named after what your program is called or does) you can start up other globals (maybe that have their own threads). This lets you control the setting up of program objects in the main objects constructor and tearing them down again in the right order when the application stops in this main objects destructor. Using static classes directly makes it tricky to initialize/uninitialize any resources these classes use in a controlled manner. This main global object also has properties for getting at the interfaces of different sub-systems of your application that various objects may want to get hold of to do their work.
I also pass references to relevant data-structures into constructors of some objects where I feel it is useful to isolate those objects from the rest of the world within the program when they only need to be concerned with a small part of it.
Whether an object grabs the global object and navigates its properties to get the interfaces it wants or gets passed the interfaces it uses via its constructor is a matter of taste and intuition. Any object you're implementing that you think might be reused in some other project should definately be passed data structures it should use via its constructor. Objects that grab the global object should be more to do with the infrastructure of your application.
Objects that receive interfaces they use via the constructor are probably easier to unit-test because you can feed them a mock interface, and tickle their methods to make sure they return the right arguments or interact with mock interfaces correctly. To test objects that access the main global object, you have to mock up the main global object so that when they request interfaces (I often call these services) from it they get appropriate mock objects and can be tested against them.
I prefer using the singleton pattern as described in the GoF book for these situations. A singleton is not the same as either of the three options described in the question. The constructor is private (or protected) so that it cannot be used just anywhere. You use a get() function (or whatever you prefer to call it) to obtain an instance. However, the architecture of the singleton class guarantees that each call to get() returns the same instance.
We should take care not to confuse Object Oriented Design with Object Oriented Implementation. Al too often, the term OO Design is used to judge an implementation, just as, imho, it is here.
Design
If in your design you see a lot of objects having a reference to exactly the same object, that means a lot of arrows. The designer should feel an itch here. He should verify whether this object is just commonly used, or if it is really a utility (e.g. a COM factory, a registry of some kind, ...).
From the project's requirements, he can see if it really needs to be a singleton (e.g. 'The Internet'), or if the object is shared because it's too general or too expensive or whatsoever.
Implementation
When you are asked to implement an OO Design in an OO language, you face a lot of decisions, like the one you mentioned: how should I implement all the arrows to the oft used object in the design?
That's the point where questions are addressed about 'static member', 'global variable' , 'god class' and 'a-lot-of-function-arguments'.
The Design phase should have clarified if the object needs to be a singleton or not. The implementation phase will decide on how this singleness will be represented in the program.
Option 3) while not purist OO, tends to be the most reasonable solution. But I would not make your class a singleton; and use some other object as a static 'dictionary' to manage those shared resources.
I don't like any of your proposed solutions:
You are passing around a bunch of "context" objects - the things that use them don't specify what fields or pieces of data they are really interested in
See here for a description of the God Object pattern. This is the worst of all worlds
Simply do not ever use Singleton objects for anything. You seem to have identified a few of the potential problems yourself