Abstraction with respective to end user users perspective - oop

its very simple and basic question.
I have a query regarding abstraction:
Abstraction is defined as Showing what is necessary from user's perspective! its filtering un-necessary info from users perspective.
its right.
example:
Implementation of Abstraction
To implement abstraction let's take an example of a car. We knows a car, Car is made of name of car, color of car, steering, gear, rear view mirror, brakes, silencer, exhaust system, diesel engine, car battery, car engine and other internal machine details etc.
Now lets think in terms of Car rider or a person who is riding a car. So to drive a car what a car rider should know from above category before he starts a car driving.
Necessary things means compulsory to know before starting a car
Name of Car
Color of Car
Steering
Rear View Mirror
Brakes
Gear
Unnecessary things means not that compulsory to know for a Car rider
Internal Details of a Car
Car Engine
Diesel Engine
Exhaust System
Silencer
In Driver perspective. That is okay. Its classic implementation of the Abstraction.
Now, what if I am different user of the class, say Mechanic??? it will be very weird to define same class for me with different access modifiers.
Right?
Please let know.

So you want to provide multiple simplified interfaces for a complex class or set of classes.
The standard way to do this is by implementing the facade design pattern. This will also encourage you to put each of the different aspects of the car into its own class and aggregate these classes only when the full functionality is required.

Related

Preventing a huge Player class for a game

So I am developing a web text-based game and whatever business requirement shows up it adds a new method to the Player class. If you have developed a game in OOP way you possible know what I am talking about.
On my daily job I am developing a game server project and again, it has a HUGE Player class. The way they made that class to not be even bigger is making something like "managers": PlayerAttributeManager, PlayerFoodManager and those are just examples. So you would not call Player.getFood, Player.getTastyFood and so on, but those would be in PlayerFoodManager for example.
A friend was making a game for android and again most if his logic was in the Player class. However a huge Player class does not break the design patterns I think, because in those games a Player can do so much things and everything is related to the player.
Please give me any advice on how to have a smaller class when creating a game.
A way to keep your Player class small(er) is to take the OOP pattern further. Let's assume that your player does, at the moment, know about food, knows how to eat, etc. Why not factor out those things and take a different point of view: Your player has, for want of a better word, a digestion - or, in OOP, an attribute of type "Digestion", which is in itself a class covering hunger, eating, etc.
A similar principle can be applied to other aspects of your player.
At the end, your player would have fields of type Digestion, Health, Armory, ..., and these aspects would be self-contained classes, keeping the player class small.
Of course, health would have some interaction with digestion presumably - this can be managed by using interfaces.

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.

encapsulation vs abstraction real world example

For an example of encapsulation i can think of the interaction between a user and a mobile phone. The user does not need to know the internal working of the mobile phone to operate, so this is called abstraction. But where does encapsulation fit in to this example? Could someone please shed some light on this?
Encapsulation is a way to achieve "information hiding" so, following your example, you don't "need to know the internal working of the mobile phone to operate" with it. You have an interface to use the device behaviour without knowing implementation details.
Abstraction on the other side, can be explained as the capability to use the same interface for different objects. Different implementations of the same interface can exist. Details are hidden by encapsulation.
Abstraction : you'll never buy a "device", but always buy something more specific : iPhone, GSII, Nokia 3310... Here, iPhone, GSII and N3310 are concrete things, device is abstract.
Encapsulation : you've got several devices, all of them have got a USB port. You don't know what kind of printed circuit there's back, you just have to know you'll be able to plug a USB cable into it.
Abstraction is a concept, which is allowed by encapsulation. My example wasn't the best one (there's no real link between the two blocks).
You can do encapsulation without using abstraction, but if you wanna use some abstraction in your projects, you'll need encapsulation.
Encapsulation is to hide the variables or something inside a class, preventing unauthorized parties to use. So the public methods like getter and setter access it and the other classes call these methods for accessing
Abstraction involves the facility to define objects that represent abstract "actors" that can perform work, report on and change their state, and "communicate" with other objects in the system.
Consider the below real time example:
Encapsulation:
As a driver you know how to start the car by pressing the start button and internal details of the starting operations are hidden from you. So the entire starting process is hidden from you otherwise we can tell starting operation is encapsulated from you.
OR
The driving wheel is encapsulated the process of rotating the wheel from you.
Abstraction:
Before mentioning anything about abstraction, we can take three different users here (I am calling them as entity)
1) You 2) Local Mechanic 3) Expert
You Entity: Since you know only to start the car by pressing a button and all other operations behind the scene are abstracted from you.
Local Mechanic Entity: Our local mechanic knows some of the implementation of starting the car, i.e. he can open car's bonnet and check the battery cable or chock etc. So in short Local Mechanic Entity knows some of the implementations of the car.
Expert Entity: Since our expert (Designer of the car) mechanic knows all the operations of our car, he can repair it very quickly. So in short Expert Entity knows all the implementations of the car.
The car's operation is completely abstracted from you and it is partially implemented to Local Mechanic Entity and fully implemented to Expert Entity. So you are an abstract class having only abstract methods, Local Mechanic Entity has extended You(Since he is also an ordinary user) and he implemented some of the methods and last our expert Entity extending Local Mechanic and implementing all the methods.
I think this is a good example.
In General words,Abstraction is Just Hiding the complex things behind a particular Procedure to make the procedure look simple.
Example:Monitor ON/OFF::--The user doesn't need to know much about all the chips functioning that happens when Monitor is switched ON or OFF..All he needs to know is On Function ON-Monitor is On and on function OFF-Monitor is off...
Or Better Look for a car--Everyone Knows that There's a special Gear machine Which changes the gear,nobody bother to know what all functionality undergoes for a gear to change..So,That's abstraction(avoiding unwanted implementations to prevent Complexity).
So,If a developer provides a good abstraction, users won't be tempted to peek at the object's internal mechanisms.
Abstraction is achieved by making class abstract having one or more methods abstract. Which is nothing but essential characteristic which should be implemented by the class extending it.
e.g. when you inventing/designing a car you define a characteristics like car should have 4 doors, break, steering wheel etc… so anyone uses this design should include this characteristics. Implementation is not the head each of abstraction. It will just define characteristics which should be included.
Encapsulation is restricting a user to follow a particular procedure to access control of a particular process.It Just provides safety and ensures system robustness.
Example:We can consider The HR in a company as a person that works on the principle of Encapsulation.i.e. we cannot talk to other departments directly we need to communicate through them through HR.This ensures security and better maintenance of company's records.
Together we can take example of a UNDER CONSTRUCTION BUILDING..where we can say that things like 'no. of managers' required,Types of Materials,No of workers etc as abstraction as they need to there in every Building Construction.
But,at the same time,Inclusion of every such field into a CONTRACTOR which acts as a mediator between the workers and the Building-Investor can be looked upon as Encapsulation.
As,It hides all the above properties into one Entity.
Hence If you would have understood till now you can say that
abstraction is just a subset of ENCAPSULATION.i.e.Every entity that
performs abstraction is encapsulated internally but every thing that
shows encapsulation need not be abstraction always.
e.g. .ToString() Method defined in almost every class is implementation of Abstraction because We don't the functionaltiy Within,all we care is that it changes almost everything to string.And as it assembles a s a unit,it is encapsulated too..But,The private members that we hide and access through Properties is an example of encapsulation only as it is done basically keeping data security in mindd..!!
Hope This answers your Question..!!
Everything has many properties and behaviours so take whatever object you want TV, Mobile, Car, Human or anything.
Abstraction:
Process of picking the essence of an object you really need
In other words, pick the properties you need from the object
Example:
a. TV - Sound, Visuals, Power Input, Channels Input.
b. Mobile - Button/Touch screen, power button, volume button, sim port.
c. Car - Steering, Break, Clutch, Accelerator, Key Hole.
d. Human - Voice, Body, Eye Sight, Hearing, Emotions.
Encapsulation:
Process of hiding the details of an object you don't need
In other words, hide the properties and operations you don't need from the object but are required for the object to work properly
Example:
a. TV - Internal and connections of Speaker, Display, Power distribution b/w components, Channel mechanism.
b. Mobile - How the input is parsed and processed, How pressing a button on/off or changes volumes, how sim will connect to service providers.
c. Car - How turning steering turns the car, How break slow or stops the car, How clutch works, How accelerator increases speed, How key hole switch on/of the car.
d. Human - How voice is produced, What's inside the body, How eye sight works, How hearing works, How emotions generate and effect us.
ABSTRACT everything you need and ENCAPSULATE everything you don't need ;)
The wording of your question is odd - Abstraction vs Encapsulation?
It should be - someone explain abstraction and encapsulation...
Abstraction is understanding the essence of the thing.
A real world example is abstract art. The artists of this style try to capture/paint the essence of the thing that still allows it to be the thing. This brown smear of 4 lines captures the essence of what a bull is.
Encapsulation is black boxing.
A cell phone is a great example. I have no idea how the cell phone connects to a satellite, tower, or another phone. I have no idea how the damn thing understands my key presses or how it takes and sends pictures to an email address or another phone number. I have no idea about the intricate details of most of how a modern smart phone works. But, I can use it! The phones have standard interfaces (yes - both literal and software design) that allows someone who understand the basics of one to use almost all of them.
How are the two related?
Both abstraction and encapsulation are underlying foundations of object oriented thought and design. So, in our cell phone example. The notion of a smart phone is an abstraction, within which certain features and services are encapsulated. The iPhone and Galaxy are further abstractions of the higher level abstraction. Your physical iPhone or Galaxy are concrete examples of multiple layers of abstractions which contain encapsulated features and services.
Abstraction
Means We focus on the essential qualities of some thing rather than one specific example and we automatically discard what is unimportant or irrelevant.
Example
We are writing a bank account class,essential qualities of bank account are Opening date, Account title,Account number,Balance etc...
Encapsulation
Means the idea of capsulation or surrounding some thing not just to keep the content together but also to protect and restrict form accessing out side.Along with secrecy It's about reducing dependencies between different parts of the application.
Example
In our Bank account class Someone accessing the attribute of Balance and trying to change it ,Attempt can be successful if there is no encapsulation.
Encapsulation is hiding information.
Abstraction is hiding the functionality details.
Encapsulation is performed by constructing the class. Abstraction is achieved by creating either Abstract Classes or Interfaces on top of your class.
In the example given in the question, we are using the class for its functionality and we don't care about how the device achieves that. So we can say the details of the phone are "abstracted" from us.
Encapsulation is hiding WHAT THE PHONE USES to achieve whatever it does; Abstraction is hiding HOW IT DOES it.-
Encapsulation helps in adhering to Single Responsibility principle and Abstraction helps in adhering to Code to Interface and not to implement.
Say I have a class for Car : Service Provider Class and Driver Class : Service Consumer Class.
For Abstraction : we define abstract Class for CAR and define all the abstract methods in it , which are function available in the car like : changeGear(), applyBrake().
Now the actual Car (Concrete Class i.e. like Mercedes , BMW will implement these methods in their own way and abstract the execution and end user will still apply break and change gear for particular concrete car instance and polymorphically the execution will happen as defined in concrete class.
For Encapsulation : Now say Mercedes come up with new feature/technology: Anti Skid Braking, while implementing the applyBrake(), it will encapsulate this feature in applyBrake() method and thus providing cohesion, and service consumer will still access by same method applyBrake() of the car object.
Thus Encapsulation lets further in same concrete class implementation.
I feel like encapsulation may make more sense to discuss when you see HOW NOT TO DO in programming. For example, consider a Car class as below.
class Car{
public float speed =0;
public boolean isReverse = false;
public boolean isStarted = false;
}
The client code may use above car class as below.
class Main{
public static void main(args String[]){
Car car = new Car();
// No need to start??
car.speed = 100; // Turbo mode directly to 100
car.speed = 0; // Turbo break
}
}
See more at: http://brevitaz.com/encapsulation-example-benefits-java/
This is uncontrolled access to car speed and other variables. By encapsulation, Car class can have complete control over how the data variables within car class can be modified.
Any concrete entity that has some behavior is example of Encapsulation. The behavior is provided by wrapping up something and hiding something from client.In case of mobile, it is signals, chips, circuits, battery and so on.
For abstraction of the same example - normal user may say I am ok with anything using which I can make calls and receive calls. This abstraction can be substituted by any concrete mobile. Check out Abstraction examples.
Let me give my 2 cents of a real-world example-analogy close to IT.
Lets say you have a subscription site, e.g a wordpress site
Each user has a role, eg admin, subscriber and so on. Many users can be admins, subscribers etc..
So abstraction here is reflected in the fact that any user with admin role can do a set of things, it does not matter which specific user this is (this is an example of abstraction).
On the other hand, subscriber users do not have access to certain settings of the site, thus some internals of the application are encapsulated for plain subscribers (this is an example of encapsulation)
As one can see abstraction and encapsulation are relative concepts, they apply with respect to something specific.
One can follow this line of reasoning and explain polymoprhism and inheritance.
For example super-admin users could do all the things admin users could do, plus some more. Moreover, if admin roles get an update in functionality, super-admins would get the same update. Thus one can see here an example of inheritance, in that super-admin roles inherit all the properties of admin roles and extend them. Note that for most part of the site, admins are interchangeable with super-admins (meaning a super-admin user can easily be used in place of an admin user, but not vice-versa in general).
I guess an egg shell can be consider the encapsulation and the contents the abstraction. The shell protects the information. You cant have the contents of an egg without the shell.,,LOL
If you have seen important TV machine, TV connections and TV color tube is hidden inside the TV case which is not been exposed for viewers like us and exposed only neccessary things of a TV like TV Channel keys, TV volume keys, ON/OFF switch, Cable Switch and TV remote control for viewers to use it.This means TV machine, TV connections and TV color tube is an unwanted data and not needed for viewers to see is been hidden from outside the world
So encapsulation means hiding the important features of a class which is not been needed to be exposed outside of a class and exposing only necessary things of a class.
Here hidden part of a class acts like Encapsulation and exposed part of a class acts like Abstraction.
Just think of Abstraction as hiding the keypad and display screen details,
Encapsulation as hiding the internal circuitry that binds them.
Abstration which hide internal detail to outside world for example you create a class(like calculator one of the class) but for end use you provide object of class ,With the help of object they will play and perform operation ,He does't aware what type of mechanism use internally .Object of class in abstract form .
Encapsulation is the technique of making the fields in a class private and providing access to the fields via public methods. If a field is declared private, it cannot be accessed by anyone outside the class, thereby hiding the fields within the class. For this reason, encapsulation is also referred to as data hiding.For example class calculator which contain private methods getAdd,getMultiply .
Mybe above answer will help you to understand the concept .
Abstraction
It is used to manage complexities of OOPs. By using this property we can provide essential features of an object to the user without including its background explanations. For example, when sending message to a friend we simply write the message, say "hiiii" and press "send" and the message gets delivered to its destination (her,friend). Here we see abstraction at work, ie we are less concerned with the internal working of mobile that is responsible for sending and receiving message
Abstraction
We use many abstractions in our day-to-day lives.Consider a car.Most of us have an abstract view of how a car works.We know how to interact with it to get it to do what we want it to do: we put in gas, turn a key, press some pedals, and so on. But we don't necessarily understand what is going on inside the car to make it move and we don't need to.
Millions of us use cars everyday without understanding the details of how they work.Abstraction helps us get to school or work!
A program can be designed as a set of interacting abstractions. In Java, these abstractions are captured in classes. The creator of a class obviusly has to know its interface, just as the driver of a car can use the vehicle without knowing how the engine works.
Encapsulation
Consider a Banking system.Banking system have properties like account no,account type,balance ..etc. If someone is trying to change the balance of the account,attempt can be successful if there is no encapsulation.
Therefore encapsulation allows class to have complete control over their properties.
Let me explain both abstraction and encapsulation with the help of the example given by you about the mobile phone.
Abstraction
The inner working on the mobile phone is hidden from the user. The user is interacting with the mobile through screen/buttons. This is equivalent to interacting with the class through an object. Here class is the mobile and the object is the screen/buttons.
Encapsulation
In a mobile phone, we can see that the battery, CPU, RAM, Camera and so on are contained together inside a box/container. This is similar to how class encapsulates all its methods and variables. The methods and variables are contained inside the class.
Also, you can't access the inner components of the mobile phone right? You need special screwdrivers for that. The components inside the mobile phone are secured. Similarly, we can secure the components or variables inside a class. We secure it with private access modifiers. Private access modifiers are the containers of the mobile phone. We can access the private fields with the help of setters and getters. These getters and setters are like special screwdrivers.

Object oriented design, define relationship

I am getting really confused about OOD when designing relatively large system. Always, we talk about has-a relationship between two entities. My question is about which one owns the other?
when designing a parking lot, there are many parking space. Should the car has an data field called parking space, or should the parking space hold the car? or both?
in a library reservation system, I am assuming there is a class Library, a class Book, and a class User. Shall the user call checkout(book), or the book call checkout(user), or the library call checkout(book, user)?
It's been very confusing for me. Any comment/suggestion is welcomed.
Lily
It depends on the situation, and what you mean by "own".
In your first example there is a one-one relationship between a car and a parking space. From a database perspective you will have to make a judgement about which should "own" the other (which table 'owns' the foreign key). You would base this judgement on expected usage - for example - since a parking space is likely to remain fixed, but you have cars coming and going all the time, it might make more logical sense for the carpark to "own" the car. That's where your design skills come into play.
In the second example, it seems to me that a single book can only be checked out to one user at a time, and "checking out" is an action that occurs on a book. Therefore the correct solution is Book.checkout(user). Building on that, a user is likely to checkout more than one book at a time, so I would be inclined to do have a checkout method on Library, such that Library.checkout(Books[], user) called Book.checkout(user) in turn.
For #1, the parking space should keep a record of if it is occupied and if so, what car is in it. Otherwise to see if you could park somewhere, you would have to poll every car to see if they are in that spot.
My immediate thinking for #2 is that it should be Library.checkout(Book, User) such that you make a note that a User has checked out a specific book.
This is heavily dependent on what you're trying to do however, and you should design it in such a way that is easiest for the problem at hand.
Sometimes replicating the data in two places isn't a terrible idea as long as you keep it synchronized. For instance, if you need to know where a specific car is parked, you're going to end up wanting to keep track of that data in the Car class as well, otherwise you're going to have to poll every parking spot to know if that car is parked there.
In Object Oriented design the object can be considered an entity. At this point you may use the Entity relationship modelling to better understand who has to own what.
When you design your model you shouldn’t care how you are going to implement it. I mean you shouldn’t think who is going to own what because this is another process of the design that is when you are going to convert your model to objects (that can be data table, XML, C# object ,…. ) : only at this point against the relationship the entity got you can decide who has to own what(sometime even against the requirements as I’ll show you later).
At the design time you must focus just on the requirements you have. In the case of the car and car parking you should think about :
How many park car one can occupied ?
How many cars a park can host ?
What kind of answer has my system to answer ? EX: as user I want know where a car is parked against its car plate number (in this case the previous answer would be wrong because if you let the park own the car you should iterate through the park to get what car is on it)
As you can see it really depends by you business requirements especially when you have “one-to-one” relationship(as in this case).
So I can suggest you to have a look at “Entity relationship Modelling” and stick to its concept to better design you object model.
In this case undoubtedly parking space should hold a car(it's called aggregation), because the relationship between car and parking space isn't permanent(different cars can be parked in the same parking place in the same day)
In this case, I think, the user wants to get a book, so the GUI of this system must have some button(or smht else) that user has to click to reserve a book. So, user calls a method checkout(book) of the system(object Library represents it) to check if the book is free(or available). Then the system(Library) checks whether the book wasn't reserved earlier by other user, so it calls method Book.check() for all instances of this book. In such solution every user account in the system should have a list of reserved books which method Book.check() uses.
To think out of box, I don't think the examples you provided have a natural "has a" or "owns a" relationship, and there are more relationships than "has a" or "owns a". In my opinion, I'd like to use a loosely coupled relationship for your examples, in implementation perspective, I would use a map to describe and maintain this relationship, which means, for a parking lot and a car, I would put a map in the Parking class, and map its slots to cars, if we find a slot existing in the map, we know that slot is occupied, if not, it's a free slot, for me, it doesn't make much sense either saying car owns the slot or the slot owns the car; for the library example, the same thing, the book and its borrower are in a very loose relationship, I'd put a map in the Library class, and map the book to its borrower. And who's the guy really does the checkout action? it's either the library staff or the auto machine or simply the library, so we can have a library.checkout(user, books), and inside the method, put books and user into the map.
For the bonus, what is really a "has a" relationship scenario? not a man has a car, this is not really a "has a", even we have "has a" in the sentence (don't let the human language mislead you), this just means, inside the car's class, there is a String field called ownerName or ownerId, that's it. One example for a real "has a" relationship scenario is human has a heart or a car has an engine, which means, in the implementation, there is really a Heart class field inside the Human Class.
How beautiful the object oriented design is!

Whether to model a car object (and its parts such as engine) with has-a (composition) or is-a (inheritance)?

I am developing a class library which will include the object Car.
The dilemma is, Car itself will be a class with fields such as Registration Number, and other general information on the car.
But a car has an engine, chassis, etc. These objects need to be modelled too. Should they be classes embedded within Car? If not, what is the usage scenario of an embedded class?
I've learnt that composition is "part of", so you can model seperate classes and use the engine type, for example, at the field level of the car to achieve this. However, "aggregation", which is a "has a" relationship with the type being passed in the ctor, also applies (a car "has an" engine).
Which way do I go?
EDIT: I am currently on homework hence the lack of a reply from me. The class library is for a web app based around cars. I am a professional developer (I develop in .NET for a living but as a junior) so this is not a homework question.
Thanks
It really depends on your application.
For example, you could implement the wheels as separate classes, containing information about what tyre is on it, how worn it is, etc. but if your app doesn't even care about the wheels then the entire class is a waste of code.
I can see three use cases for composition:
The owning class has gotten overly complicated and should be broken down.
The owning class has multiple copies of a set of properties that could be mapped into a class. This allows you to bind all those properties together.
The contained object may need to be inspected or considered separately from the object that owns it (eg. you might want to move the Engine object to another car) or may be replaced as a single unit.
In summary: Use composition as a tool for encapsulating complexity or eliminating repetition. If it doesn't serve one of those purposes it probably isn't worth making a new class for.
A class should have as few responsibilities as possible and encapsulate and delegate other functionality to other classes. Lots of a small, simple classes that do one thing is a sign of a readable, stable codebase.
Yes, a car will "have" an engine, but I'd suggest using an interface for this and similar "has a" relationships. Again, depending on the professor, you might get bonus points for having a factory create different cars (appropriate, no?):
public class Car
{
private Engine engine;
public Car(Engine engine)
{
this.engine = engine;
}
public void accelerate()
{
this.engine.goFaster();
}
public void decelerate()
{
this.engine.goSlower();
}
}
public interface Engine
{
public void goFaster();
public void goSlower();
}
public class ReallyFastEngine implements Engine
{
public void goFaster()
{
// some code that goes really fast
}
public void goSlower()
{
// some code that goes slower
}
}
public class NotAsFastEngine implements Engine
{
public void goFaster()
{
// some code that goes not as fast
}
public void goSlower()
{
// some code that goes slower
}
}
public class CarFactory()
{
public static Car createFastCar()
{
return new Car(new ReallyFastEngine());
}
public static Car createNotAsFastCar()
{
return new Car(new NotAsFastEngine());
}
}
Seeing as it is homework, and depending on the inclinations of your tutor/professor/teacher, you are probably better to go down the route of writing a separate classes for the engine, wheels and so on. Even though it may be completely over-engineered, and your application may not care about them, it is possible that your homework will be marked by standards such as:
"Did they identify an engine class"
"Does it have sensible methods like Start()"
"Mark them down for lumping everything in one big class that is actually simpler, because they clearly don't understand composition"
Or whatever, and not the kinds of standards that the more pragmatic people in this thread apply to their own designs.
Only break down the model of the car into pieces that will be exposed as separate entities outside the scope of the car. Another way to think about it is do you really understand how your car gets started when you turn the key? As far as the typical driver is concerned, everything under the hood is one big (and noisy) black box. The auto-engineers know the common parts that need maintenance by the car owner and have explicitly designed them for a different level of user interaction, things like the oil dipstick or coolant reservoir refill cap.
Can you model each piece of the car? Sure. Is it helpful to model the individual spark plugs? Probably not.
Do you need cars with different attributes like color or size? Do you need cars with different capabilities like passenger or towing capacity? The one place that is different is if you need cars with different behaviors. This is where you really need to think about modeling a Driver object which has attributes, from simple ones like reaction-time to complex ones like aggressiveness.
Modeling vehicles as examples of object orientation or inheritance is problematic because the examples don't really explain the true distinctions between essential attributes that define a class. It's not new to StackOverflow but this question isn't a duplicate either, see this SO thread. I had this same discussion with a friend of mine and posted a log of it on my blog. Read up on the different aircraft types the FAA recognizes and how the regulations for each type are subdivided. There are lots of different types of aircraft, the biggest separation is between powered and unpowered.
Check out the definitions used by the FAA:
Aircraft means a device that is used
or intended to be used for flight in
the air.
Airplane means an engine-driven
fixed-wing aircraft heavier than air,
that is supported in flight by the
dynamic reaction of the air against
its wings.
Airship means an engine-driven
lighter-than-air aircraft that can be
steered.
There is also lighter-than-air and heavier-than-air. A hot-air balloon is unpowered and lighter-than-air. A blimp is powered and lighter-than-air. A glider is unpowered and heavier-than-air. A Boeing 757 is powered and heavier-than air but adds another category of 'fixed-wing' which is unlike a helicopter which is also powered and heavier-than-air but is 'rotary-wing'.
Here is the first four in the form of a table:
| Powered | Unpowered
---------------------------------------------------
Lighter-than-air | Blimp | Hot-air balloon
Heavier-than-air | 737 | Glider
You get the picture.
You can't just say you'll model the engine separately from the car because a car without an engine might be a whole different animal. A car without an engine is nothing like a trailer, which also doesn't have an engine but never will either. In these cases neither 'is-a' nor 'has-a' fits in the concrete way we build objects. You don't declare a blimp as being a aircraft that 'is-a' lighter-than-air, so is a hot-air balloon. The fact that they are both lighter-than-air doesn't make them related in any way except the physics they exploit. The distinction is important because the rules and regulations that apply are different. From the other angle, we don't describe a blimp as a hot-air balloon that 'has-a' engine. The aircraft aren't physically related, the relationship is how they should be handled.
If you don't need to define your objects to that level of detail, you may not need to model them to that level of detail either.
Car will be an top hierarchy object. Including simple fields like Number, ID or description.
And will have complicated fields like Engine, which is an object by itself.
So the Car will look something like:
class Car{
String ID;
Engine engine;
}
That a has-a relation.
One criteria you can have to decide whether the classes for Engine, Chasis etc.
needs to be present as an inner class (embedded class) is whether instance of
these classes can be used elsewhere in your application. In such cases the
decision is simple and it is to make these classes exist separately
(not as inner classes).
Even if these classes are not used elsewhere in your application then other
criteria can be testability. With these classes embedded inside and with your
design is it possible to have unit tests that can appropriately test your
code providing a good coverage.
For example say, if you have made an instance variable which references an
Engine object and this variable is being initialized in the Constructor of Car.And
your Engine class has some methods which needs to be tested. Then how can
you add unit tests to check the code in Engine class ? Probably you would
have some methods in Car class which expose the behavior or Engine class allowing
you to write unit tests. Then the question is if there is a need to expose
the behavior of Engine class wouldn't it be better that the Engine class
stands on it own?
Alternatively there might not be a need to explicitly test the methods in
Engine class and unit testing the methods in Car covers the Engine class code
as well. Then it reflects tight integration of Engine class with the Car class
and would mean it can remain as an inner class.
It depends on what it is you're trying to do. Trying to design a 'Car' class (or any other class for that matter) without an idea of the use cases is an exercise in futility.
You will design the classes and their relationships and interactions very differently depending on the use cases you're trying to enable.