What you consider FooBuilder and Foo is actually part of a well-established Builder pattern. The other approach you mention with creating a Foo instance based on an existing instance is called a Prototype pattern. Both of these are well-known object creation alternatives and several books (most notably "Design Patterns", aka GoF) have been written describing them. (not sure I'm clear on your second mutable example, so comparing #1 to #3 here)
Each pattern obviously has its own advantages and drawbacks and only you can decide which one is better for your specific situation. For example, I would typically use builders when there's a lot of different ways of initializing Foo. For example, right now I'm working on a query builder class and many clients use it differently to build query objects. Different clients want different fields to be returned, some clients want only last 10 rows, some want sorting while others don't. Builder is perfect as it can look something like this:
qb = QueryBuilder()
query = qb.fields("name", "address")
.sort("zip", "asc")
.limit(10)
.build()
So multiple setters, each returning instance of the builder itself so you can daisy-chain basically serve as a very flexible constructor. Making one class a friend of another class has it's time and a place and potentially this could be one of those places.
Alternatively, you could define Foo as having one constructor that takes a rather complex set of params, or potentially you could define another class FooData, that FooBuilder could initialize and pass into Foo creation. Then again, maybe Foo and FooBuilder being friends in this case isn't such a bad thing. Just keep in mind that when one class is a friend of another one, you are expanding encapsulation boundary, which could be just as bad as putting more and more code all within one class (i.e. more code knows about internals)
At the end of the day, you could be thinking and considering all these different options and it will all boil down to 60/40. If there's no clear winner, you can always let a coin pick the winner and just go with it. Most likely either one of the design choices would work just fine and by going through the motions and seeing your code in action you will learn valuable lesson for future. Sometimes when I have design decisions and can't decide between A and B, I could end up picking B and then if I ever come across a similar situation I would intentionally pick the other choice. The work in either case gets done and I get the software to do what I want, but you get a ton of benefit of actually seeing your decisions in action and being able to compare the two working approaches, rather than just discussing and thinking about them.
The question asks "which process determines which method should execute?"
This is a bad question.
But, we can immediately eliminate three of the choices: Is-A, Has-A, and Parent Class, since those are object-oriented, but not certainly not processes. Even if Is-A and Has-A were processes, they would be processes regarding class and composition, as you said, not method execution.
Inheritance is a process (also a concept), a process of inheriting the traits of the parent class. By that definition alone, we can eliminate it.
That leaves us with only Polymorphism, which is part of why this is a bad question. Polymorphism sounds like a concept, more than a process. However, if considered to be a process, it would be a process of "polymorphing" or "taking a different shape". An answer on Stack Overflow says:
So polymorphism is the ability (in programming) to present the same interface for differing underlying forms (data types).
By that definition, we're talking about a process where an object can act as one or more underlying real types. You have an interface, and the underlying data types determine which method should actually be called.
We're looking for a process that matches the statement "determining which method in a class hierarchy should execute", and I think that matches pretty well.
It's also a bad question because that statement could mean many other things, and I don't think many people would really described the "determining" part to be the polymorphism -- instead, I'd consider polymorphism to be the definition part.
Best Answer
No, it is not right that an "object" is always an instance of a class. Just for example, the standard for C (which doesn't have classes at all) defines an object as (ยง3.14/1): "region of data storage in the execution environment, the contents of which can represent values."
Now, it is true that using "object" to refer to an instance of a class is quite common. In some languages (e.g., Smalltalk) all objects are instances of classes. In others (e.g., C++) the term is somewhat ambiguous, because there is a C-like use of the term and a Smalltalk-like use of the term, so it's not necessarily clear whether "object" is being used to refer specifically to an instance of a class, or just to some region of data storage in the execution environment, which may be an instance of some primitive type rather than a class, or may be (for example) some dynamic storage that hasn't been initialized, so it's not really an instance of any type.
As far as "object instance" making sense, I can see one situation where it could. Going back to Smalltalk: everything in Smalltalk is an instance of a class -- even a class is an instance of a class (called the metaclass). In a case like this, I can see where it could (sort of) make sense to talk about an "object instance", when you were specifically talking about an instance of a class as opposed to the class of the class.
In fairness, however, that usage is undoubtedly quite rare (at most). The vast majority of the time, "object instance" is probably just sloppy wording.