Car and Paint Class Relationship - oop

Interview question:
1) There is a "Paint" class and a "Car" class, with several subclasses like Red, Blue etc colors. Explain how do you separate Colors from Car class? and how is it important?
2) Using an object oriented approach, if you have a class "Car", how would "Paint" class relate to "Car"?
Both are pretty much same questions, just wanna know different perspectives-

Car "has" Paints, I'd guess the interviewer wants you to explain Inheritance and Composition. Example, Red, Blue inherit from Paint since they have "is a" relationship, while Car has paints and it is example of composition. Then some common follow-up questions would be when to use composition over inheritance, is it better to use composition over inheritance, if so why, etc.

Related

OOP: Should I create two classes or one parent class and two subclasses if the two subclasses only differ in one attribute value?

Let's suppose I have a class Car with color and price as its only attributes.
The price depends on the color of the car.
Since car objects will only differ in color and their corresponding price, should I just create two classes or is it better to create one superclass and two subclasses which will each have their own way to calculate the price?
depends on how you feel comfortable but you should consider maybe you will have another car and it will have a different engine so my choice is to create a superclass but as i told it depends on how you feel comfortable
Its better to create one superclass and then inherit it to the other classes as it easier
instead of making 2 classes because you don't have to repeat the code and its a bad practice to do so.
Hope it helped you :)

Polymorphism and Genaralization in UML

What is the difference between polymorphism and Generalization . I saw that they look similar in UML. Are they same ?
Let's look into the Oxford dictionary:
generalization | ˌjen(ə)rələˈzāSH(ə)n |
noun
a general statement or concept obtained by inference from specific cases: he was making sweeping generalizations.
• the action of generalizing: such anecdotes cannot be a basis for generalization.
UML has a graphical representation for that which is a solod line with an open triangle towards the general class.
polymorphism | ˌpälēˈmôrfizəm |
noun
the condition of occurring in several different forms: the complexity and polymorphism of human cognition.
[...]
• Computing a feature of a programming language that allows routines to use variables of different types at different times.
That's a certain use of generalization. If you have, say, an abstract class Animal which has an operation sound() and you have different specializations (the opposite of generalization) of that class (e.g. a concrete class Cat and Dog) then you can treat the polymorph Animal by calling sound(). In case you have a Cat it would meow and for a Dog it would bark.
I assume that your question refers to generalization and polymorphism for object oriented programming, for example Java.
Generalization refers to the fact that a class can factorize behaviors and the sub class can benefit from these behaviors. The super class generalizes the behaviors and on the contrary, the sub class specializes these behaviors.
As an object can be seen as the general class or the specialized one (by casting this object), we say that this object is polymorph. At runtime, the polymorphism can influence the choice of the method call: if both super class the specialized one have two implementations of the same method, the program should choose between the two implementations.
Thus, polymorphism is more linked to the fact that at runtime, we have to choose about the nature of the object, whereas generalization is more linked to the concept of inheritance and factorization of behaviors.
You can have a look to these lecture notes for more explanations and examples.

Composition vs Aggregation

Let us say I have a car class and paint class(which consists of different colors). Now In terms of Object oriented design what can be the relation between these two classes is it composition or aggregation. First I thought it would be composition and then I thought it would be aggregation since even if car class is destroyed paint can exist independently. Am I thinking right over here?
I would say it depends on the context of your model. What does your Paint class specifically represent? Is it "a paint job specific to that car"? If so, it is part-of that car and would be considered composition. If it is paint as an independent concept, and an instance can be applied to multiple cars, then a car has-a Paint instance, and it would be considered aggregation.
Your example is a bit awkward but the question you're asking is exactly what you must answer in order to have the answer. No one but you can answer what is correct for your system.
For example, it will be composition if you're actually talking about an applied paint since it can't reuse/reapply/have paint without a recipient (e.g., a car). It should also be a composition if in your system there is no use for independent paint object.
On the other hand, if a paint is a spray container, it can very much exist without the car concept and can be applied to different cars.
It depends on the circumstance, it would be aggregation IMO as there is no strong relationship between a car and its paint, if the paint is removed it does not actually affects the functioning of the car,
But if you think of a relationship between car and engine and if you remove the engine the car cannot move. So this will be composition.

Is Car class violating Single Responsibility Principle?

Even thought I think I understand Single Responsibility Principle and high/low cohesion principle, the following questions are still causing me some confusion
1) Assume Planet and Bird properties are put arbitrarily / at random in Car class ( ie. no code within Car needs or operates on the two objects returned by these two properties ) - in other words, Planet and Bird properties don't belong in Car class
a)
SRP states that object should have only one reason to change.
public class Car
{
public void StartEngine()
{ ... }
private Planet Planet
{
get { ... }
}
private Bird Bird
{
get { ... }
}
}
Is Car class violating SRP? I would say it doesn't break SRP, since any changes to Planet or Bird instances don't propagate to the Car class?
b)
Cohesion refers to how closely related methods and class level
variables are in a class. In highly cohesive class all the methods
and class level variables are used together to accomplish a specific
task. In a class with low cohesion functions are randomly inserted
into a class and used to accomplish a variety of different tasks
Assume that even though Car class contains these two random properties, it still accomplishes just a single specific task ( or several closely related task ):
Would we say that Car has low cohesion, even though it still performs a specific task ( or several closely related tasks )?
2) Assume that Planet and Bird properties are used by methods of a Car instance to accomplish a specific task, would then Car have high cohesion, even though conceptually the two properties don't belong to Car ( and thus it would be better if instead Planet and Bird instances were passed as arguments to a methods of a Car which operate on them )
thank you
HELTONBIKER:
1)
as you encapsulated Bird and Planet inside Car (worse yet if they are
private), so now Car class has THREE reasons to change:
I fail to see how Car has three reasons to change since in my first question Car's methods don't even operate on the two properties and thus any changes to Planet's and Bird's public API won't affect Car class?
2)
The problem here has two components:
1. Bird and Planet are contained (as opposed to aggregated) in Car class;
2. Bird and Planet are not conceptually related to Car, much less by some containment relationship.
a) This is confusing: aren't the chances ( at least with my first question ) of Car having to be modified due to modification of Planet or Bird instances exactly the same regardless of whether Planet and Bird instances are contained or aggregated?
b) In second question methods of Car do operate on the two properties in order to perform a single specific task, so aren't they conceptually at least somewhat related? Would you say that even in second question class has low cohesion, even though it performs only a single task ( and is using the two properties to accomplish the task )?
The car class does have low cohesion, as it refers to classes wholly dissimilar to it's set of responsibilities. It also has a higher coupling surface, because since Planet and Bird are public, you've provided access to consumers to these properties, meaning that you're now adding two more "reasons for change" to any consumer, regardless of whether or not Car uses these internally.
At any rate, SRP has been violated if only because Car now has the responsibility of "a way to get planets or birds", disregarding any coupling/cohesion arguments.
1)
I would say that Car cannot hold Planet and Bird. That way Car has two different responsibilities: car functionality and holding some strange objects.
There should be some other object/class that would hold objects in world: eg: class WorldContainer
2)
I would say that both of your examples have low cohesion. Managing car and some different objects should be done using some other interface. Interface that would glue them together.
SRP means that a class should have only one reason to change.
So, a modification in Car class should mean that the Car conceptual model changed.
BUT, as you encapsulated Bird and Planet inside Car (worse yet if they are private), so now Car class has THREE reasons to change:
Modifying the Car conceptual model and/or behaviour;
Modifying the Bird conceptual model and/or behaviour;
Modifying the Planet conceptual model and/or behaviour;
The problem here has two components:
Bird and Planet are contained (as opposed to aggregated) in Car class;
Bird and Planet are not conceptually related to Car, much less by some containment relationship.
Or, plainly speaking (and I hope you did so as a didactic exercise), the architecture shown simply doesn't make sense.
Example with aggregation (in Python). The non-cohesive classes are defined outside the Car class definition, which references them. Car depends from Bird and Planet, but now Bird and Planet exist on their own.
class Bird():
hasWings = True
class Planet():
isFlat = False
class Car():
owner = Bird()
substrate = Planet()
Example with parameter-passing (just the car class, suppose the other classes are similar as above). Now the Car constructor (the __init__ method in python) takes instances as parameters. This might or might not be prefered. The dependency and coupling remains, but perhaps more concrete now.
class Car():
def __init__(bird, planet)
owner = bird
substrate = planet
In the end this whole issue of cohesion and coupling doesn't have so much to do with the software itself, but with the developers. Compilers won't mind if your namespaces, project folders and file distribution is messy, as long as it "compiles". But it wouldn't make ANY SENSE to do as you did (put a Bird and a Planet class inside a Car class). Just to begin, your versioning of each class would be very messed.
So, the purity you shouldn't violate is not that written in books for the sake of it. This purity is (or should have been) derived of human beings struggling with machine instructions. Object-Orientation, and Software Architecture in general, is not intended for the machine, but for the developer's (piece of) mind.

Why is the key idea behind OOP polymorphism?

In the book C++ Primer, the author wrote: "The key idea behind OOP is polymorphism". I am not sure I understand what the author meant. What about other important stuff: Abstract, Inheritance, etc.
Can anyone elaborate on that, please?
Edit:
I do not ask "What is polymorphism". I am asking "Why polymorphism is the key behind OOP"? Why not inheritance is the key?
I'm not sure that it's the key to OOP. That's just someone's opinion.
I think there are four keys: abstract data types, encapsulation, inheritance, and polymorphism. They belong together.
Each idea depends on the previous ones. ADT is the only one that stands on its own. Encapsulation needs ADT. Polymorphism requires inheritance.
Polymorphism helps to eliminate if, switch, and case statements. You don't have to write code to figure out what to do based on object type; the virtual table simply calls the right method for you behind the scenes.
The Author may be saying this because :
When class B inherits from A then class B can be typecasted to A ----> Which is also called as polymorohism. So Inheritance directly allows polymorphism.
When A implements interface I*something* then A can rome around as I*something* which is also called as polymorphism. So Interfaces makes polymorphism come true.
Abstract : Abstract class is just another class which cannt be instantiated and act as base class (generally). Non abstract Child classes can be type casted to Abstract class and hence polymorphism.
So infact its seen that most concept of OOP can be seen as polymorphism and due to this Author might have said that.
Generally it's the idea of creating objects (with their fields, methods, etc) which can have more than one form - derived (abstract) classes, implemented interfaces and so on.
And you would have had your answer in few seconds only, if you would've had asked google, wikipedia and so on, first ;)