What is it mean by "Operation applicable on object"/ "Operations on object"? - oop

I am most of the time confused with that terminology in OOP (inheritance). So lemme end my war with it today :)
consider the (language independent) code :
class rectangle {
...
void changeLength(int);
void changeWidth(int);
...
}
class square : public rectangle { ... }
int calculateArea(rectangle){ ... }
Now when xyz says that any operation applicable ( or applies to) on rectangle is also applicable on square , is xyz talking about member functions here or (any manipulation of rectangle in ) calculateArea function or both included ?

When xyz says that any operation that is provided by by a rectangle is also provided by a suqare, he is talking about all three operations. square provides calculateArea, changeLength(ing) and changeWidth(int).
When xyz says that any operation that is applicable to a rectangle is also applicable to a square, he is talking about the fact that calculateArea(rectangle) can also be called passing in an instance of a square. calculateArea itself then can call the public methods of the class. It will execute the methods of the superclass if these are not overridden in the subclass.
See also Wikipedia: Inheritance (Computer Science)
Be sure to also read the Wikipedia article mentioned by SLaks about the Circle-Ellipse-Problem which addresses some major issues with this principle.

Related

Understanding the Liskov Substitution Principle (LSP)

After reading this post I think I mostly understand LSP and most of the examples, but I can’t say I’m 100% certain from my experience of many examples of inheritance, as it seems that many examples do violate LSP and it seems difficult not to when overriding behaviour.
For instance, consider the following simple demonstration of inheritance, taken from Head First Object Oriented Analysis & Design. Aren't they violating LSP with the Jet child class?
public class Airplane {
private int speed;
public void setSpeed(int speed) {
this.speed = speed;
}
public int getSpeed() {
return speed;
}
}
public class Jet extends Airplane {
private static final int MULTIPLIER=2;
/**
* The subclass can change behaviour of its superclass, as well as call the
* superclass's methods. This is called overriding the superclass's behaviour
*/
public void set setSpeed(int speed) {
super.setSpeed(speed * MULTIPLIER);
}
public void accelerate() {
super.setSpeed(getSpeed() * 2);
}
}
A client using a reference to an instance of base class Airplane might be surprised, after setting the speed, to find it is twice as fast as expected after being passed an instance of a Jet object. Isn't Jet changing the post-conditions for the setSpeed() method and thus violating LSP?
E.g.
void takeAirplane(Airplane airplane) {
airplane.setSpeed(10);
assert airplane.getSpeed()==10;
}
This will clearly fail if takeAirplane is passed a reference to a Jet object.
It seems to me that it will be difficult not to violate LSP when “overriding a superclass’s behaviour”, yet this is one of the main/desirable features of inheritance!
Can someone explain or help clarify this? Am I missing something?
According to Wikipedia
[The Liskov substitution principle] states that, in a computer program, if S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e., objects of type S may substitute objects of type T) without altering any of the desirable properties of that program (correctness, task performed, etc.).
In the case of the Jet, it's speed being twice as fast is a violation of the LSP - it fails the postcondition that setSpeed(getSpeed(x))==x
The Liskov Substitution Principle says that it's ok to modify the behaviour of in a derived class, provided the correctness of the program does not change. It imposes restrictions on the changes you make in the derived classes.

'is instanceof' Interface bad design

Say I have a class A
class A
{
Z source;
}
Now, the context tells me that 'Z' can be an instance of different classes (say, B and C) which doesn't share any common class in their inheritance tree.
I guess the naive approach is to make 'Z' an Interface class, and make classes B and C implement it.
But something still doesn't convince me because every time an instance of class A is used, I need to know the type of 'source'. So all finishes in multiple 'ifs' making 'is instanceof' which doesn't sound quite nice. Maybe in the future some other class implements Z, and having hardcoded 'ifs' of this type definitely could break something.
The escence of the problem is that I cannot resolve the issue by adding functions to Z, because the work done in each instance type of Z is different.
I hope someone can give me and advice, maybe about some useful design pattern.
Thanks
Edit: The work 'someone' does in some place when get some instance of A is totally different depending of the class behind the interface Z. That's the problem, the entity that does the 'important job' is not Z, is someone else that wants to know who is Z.
Edit2: Maybe a concrete example would help:
class Picture
{
Artist a;
}
interface Artist
{
}
class Human : Artist { }
class Robot : Artist {}
Now somewhere I have an instance of Picture,
Picture p = getPicture();
// Now is the moment that depending if the type of `p.a` different jobs are done
// it doesn't matter any data or logic inside Human or Robot
The point of using an interface is to hide these different implementations; A should just know the intent or high-level purpose of the method(s).
The work done by each implementation of Z may be different, but the method signature used to invoke that work can be the same. Class A can just call method Z.foo(), and depending on whether the implementation of Z is B or C, different code will be executed.
The only time you need to know the real implementation type is when you need to carry out completely unrelated processing on the two different types, and they don't share an interface. But in that case, why are they being processed by the same class A? Now, there are cases where this may make sense, such as when B and C are classes generated from XML Schemas, and you can't modify them - but generally it indicates that the design can be improved.
Updated now that you've added the Picture example. I think this confirms my point - although the implementation of getPicture() is different, the purpose and the return type are the same. In both cases, the Artist returns a Picture.
If the caller wants to treat Robot-created and Human-created pictures in the same way, then they use the Artist interface. They do not need to distinguish between Human or Robot, because they just want a picture! The details of how the picture is created belong in the subclass, and the caller should not see these details. If the caller cares about precisely how a picture is created, then the caller should paint it, not the Robot or Human, and the design would be quite different.
If your subclasses are performing totally unrelated tasks (and this is not what your Artist example shows!) then you might use a very vague interface such as the standard Java Runnable; in this case, the caller really has no idea what the run() method will do - it just knows how to run things that are Runnable.
Links
The following questions/articles suggest some alternatives to instanceof:
Avoiding instanceof in Java
Alternative to instanceof approach in this case
And the following articles also gives example code, using an example that seems similar to yours:
http://www.javapractices.com/topic/TopicAction.do?Id=31
and the following articles discuss the tradeoffs of instanceof versus other approaches such as the Visitor pattern and Acyclic Visitor:
https://sites.google.com/site/steveyegge2/when-polymorphism-fails
http://butunclebob.com/ArticleS.UncleBob.VisitorVersusInstanceOf
I think you need to post more information, because as it stands what I see is a misunderstanding of OOP principles. If you used a common interface type, then by Liskov substitution principle it shouldn't matter which type source is.
I'm gonna call your A, B, and C classes Alpha, Beta, and Gamma.
Perhaps Alpha can be split into two versions, one which uses Betas and one which uses Gammas. This would avoid the instanceof checks in Alpha, which as you've surmised are indeed a code smell.
abstract class Alpha
{
abstract void useSource();
}
class BetaAlpha extends Alpha
{
Beta source;
void useSource() { source.doSomeBetaThing(); }
}
class GammaAlpha extends Alpha
{
Gamma source;
void useSource() { source.doSomeGammaThing(); }
}
In fact this is extremely common. Consider a more concrete example of a Stream class that can use either Files or Sockets. And for the purpose of the example, File and Socket are not derived from any common base class. In fact they may not even be under our control, so we can't change them.
abstract class Stream
{
abstract void open();
abstract void close();
}
class FileStream extends Stream
{
File file;
void open() { file.open(); }
void close() { file.close(); }
}
class SocketStream extends Stream
{
Socket socket;
void open() { socket.connect(); }
void close() { socket.disconnect(); }
}

Type conversion when iterating over a collection of super-type. Alternatives?

This is quite a common problem I run into. Let's hear your solutions. I'm going to use an Employee-managing application as an example:-
We've got some entity classes, some of which implement a particular interface.
public interface IEmployee { ... }
public interface IRecievesBonus { int Amount { get; } }
public class Manager : IEmployee, IRecievesBonus { ... }
public class Grunt : IEmployee /* This company sucks! */ { ... }
We've got a collection of Employees that we can iterate over. We need to grab all the objects that implement IRecievesBonus and pay the bonus.
The naive implementation goes something along the lines of:-
foreach(Employee employee in employees)
{
IRecievesBonus bonusReciever = employee as IRecievesBonus;
if(bonusReciever != null)
{
PayBonus(bonusReciever);
}
}
or alternately in C#:-
foreach(IRecievesBonus bonusReciever in employees.OfType<IRecievesBonus>())
{
PayBonus(bonusReciever);
}
We cannot modify the IEmployee interface to include details of the child type as we don't want to pollute the super-type with details that only the sub-type cares about.
We do not have an existing collection of only the subtype.
We cannot use the Visitor pattern because the element types are not stable. Also, we might have a type which implements both IRecievesBonus and IDrinksTea. Its Accept method would contain an ambiguous call to visitor.Visit(this).
Often we're forced down this route because we can't modify the super-type, nor the collection e.g. in .NET we may need to find all the Buttons on this Form via the child Controls collection. We may need to do something to the child types that depends on some aspect of the child type (e.g. the bonus amount in the example above).
Strikes me as odd that there isn't an "accepted" way to do this, given how often it comes up.
1) Is the type conversion worth avoiding?
2) Are there any alternatives I haven't thought of?
EDIT
Péter Török suggests composing Employee and pushing the type conversion further down the object tree:-
public interface IEmployee
{
public IList<IEmployeeProperty> Properties { get; }
}
public interface IEmployeeProperty { ... }
public class DrinksTeaProperty : IEmployeeProperty
{
int Sugars { get; set; }
bool Milk { get; set; }
}
foreach (IEmployee employee in employees)
{
foreach (IEmployeeProperty property in employee.Propeties)
{
// Handle duplicate properties if you need to.
// Since this is just an example, we'll just
// let the greedy ones have two cups of tea.
DrinksTeaProperty tea = property as DrinksTeaProperty;
if (tea != null)
{
MakeTea(tea.Sugers, tea.Milk);
}
}
}
In this example it's definitely worth pushing these traits out of the Employee type - particularly because some managers might drink tea and some might not - but we still have the same underlying problem of the type conversion.
Is it the case that it's "ok" so long as we do it at the right level? Or are we just moving the problem around?
The holy grail would be a variant on the Visitor pattern where:-
You can add element members without modifying all the visitors
Visitors should only visit types they're interested in visiting
The visitor can visit the member based on an interface type
Elements might implement multiple interfaces which are visited by different visitors
Doesn't involve casting or reflection
but I appreciate that's probably unrealistic.
I would definitely try to resolve this with composition instead of inheritance, by associating the needed properties/traits to Employee, instead of subclassing it.
I can give an example partly in Java, I think it's close enough to your language (C#) to be useful.
public enum EmployeeProperty {
RECEIVES_BONUS,
DRINKS_TEA,
...
}
public class Employee {
Set<EmployeeProperty> properties;
// methods to add/remove/query properties
...
}
And the modified loop would look like this:
foreach(Employee employee in employees) {
if (employee.getProperties().contains(EmployeeProperty.RECEIVES_BONUS)) {
PayBonus(employee);
}
}
This solution is much more flexible than subclassing:
it can trivially handle any combination of employee properties, while with subclassing you would experience a combinatorial explosion of subclasses as the number of properties grow,
it trivially allows you to change Employee properties runtime, while with subclassing this would require changing the concrete class of your object!
In Java, enums can have properties or (even virtual) methods themselves - I don't know whether this is possible in C#, but in the worst case, if you need more complex properties, you can implement them with a class hierarchy. (Even in this case, you are not back to square one, since you have an extra level of indirection which gives you the flexibility described above.)
Update
You are right that in the most general case (discussed in the last sentence above) the type conversion problem is not resolved, just pushed one level down on the object graph.
In general, I don't know a really satisfying solution to this problem. The typical way to handle it is using polymorphism: pull up the common interface and manipulate the objects via that, thus eliminating the need for downcasts. However, in cases when the objects in question do not have a common interface, what to do? It may help to realize that in these cases the design does not reflect reality well: practically, we created a marker interface solely to enable us to put a bunch of distinct objects into a common collection, but there is no semantical relationship between the objects.
So I believe in these cases the awkwardness of downcasts is a signal that there may be a deeper problem with our design.
You could implement a custom iterator that only iterates over the IRecievesBonus types.

Difference between object and instance

I know this sort of question has been asked before, but I still feel that the answer is too ambiguous for me (and, by extension, some/most beginners) to grasp.
I have been trying to teach myself broader concepts of programming than procedural and basic OOP. I understand the concrete concepts of OOP (you make a class that has data (members) and functions (methods) and then instantiate that class at run time to actually do stuff, that kind of thing).
I think I have a handle on what a class is (sort of a design blueprint for an instance to be created in its likeness at compile time). But if that's the case, what is an object? I also know that in prototype based languages, this can muck things up even more, but perhaps this is why there needs to be a clear distinction between object and instance in my mind.
Beyond that, I struggle with the concepts of "object" and "instance". A lot of resources that I read (including answers at SO) say that they are largely the same and that the difference is in semantics. Other people say that there is a true conceptual difference between the two.
Can the experts here at SO help a beginner have that "aha" moment to move forward in the world of OOP?
Note: this isn't homework, I don't go to school - however, I think it would help people that are looking for homework help.
A blueprint for a house design is like a class description. All the houses built from that blueprint are objects of that class. A given house is an instance.
The truth is that object oriented programming often creates confusion by creating a disconnect between the philosophical side of development and the actual mechanical workings of the computer. I'll try to contrast the two for you:
The basic concept of OOP is this: Class >> Object >> Instance.
The class = the blue print.
The Object is an actual thing that is built based on the 'blue print' (like the house).
An instance is a virtual copy (but not a real copy) of the object.
The more technical explanation of an 'instance' is that it is a 'memory reference' or a reference variable. This means that an 'instance' is a variable in memory that only has a memory address of an object in it. The object it addresses is the same object the instance is said to be 'an instance of'. If you have many instances of an object, you really just have many variables in difference places in your memory that all have the same exact memory address in it - which are all the address of the same exact object. You can't ever 'change' an instance, although it looks like you can in your code. What you really do when you 'change' an instance is you change the original object directly. Electronically, the processor goes through one extra place in memory (the reference variable/instance) before it changes the data of the original object.
The process is: processor >> memory location of instance >> memory location of original object.
Note that it doesn't matter which instance you use - the end result will always be the same. ALL the instances will continue to maintain the same exact information in their memory locations - the object's memory address - and only the object will change.
The relationship between class and object is a bit more confusing, although philosophically its the easiest to understand (blue print >> house). If the object is actual data that is held somewhere in memory, what is 'class'? It turns out that mechanically the object is an exact copy of the class. So the class is just another variable somewhere else in memory that holds the same exact information that the object does. Note the difference between the relationships:
Object is a copy of the class.
Instance is a variable that holds the memory address of the object.
You can also have multiple objects of the same class and then multiple instances of each of those objects. In these cases, each object's set of instances are equivalent in value, but the instances between objects are not. For example:
Let Class A
From Class A let Object1, Object2, and Object3.
//Object1 has the same exact value as object2 and object3, but are in different places in memory.
from Object1>> let obj1_Instance1, obj1_Instace2 , obj1_Instance3
//all of these instances are also equivalent in value and in different places in memory. Their values = Object1.MemoryAddress.
etc.
Things get messier when you start introducing types. Here's an example using types from c#:
//assume class Person exists
Person john = new Person();
Actually, this code is easier to analyze if you break it down into two parts:
Person john;
john = new Person();
In technical speak, the first line 'declares a variable of type Person. But what does that mean?? The general explanation is that I now have an empty variable that can only hold a Person object. But wait a minute - its an empty variable! There is nothing in that variables memory location. It turns out that 'types' are mechanically meaningless. Types were originally invented as a way to manage data and nothing else. Even when you declare primitive types such as int, str, chr (w/o initializing it), nothing happens within the computer. This weird syntactical aspect of programming is part of where people get the idea that classes are the blueprint of objects. OOP's have gotten even more confusing with types with delegate types, event handlers, etc. I would try not focus on them too much and just remember that they are all a misnomer. Nothing changes with the variable until its either becomes an object or is set to a memory address of an object.
The second line is also a bit confusing because it does two things at once:
The right side "new Person()" is evaluated first. It creates a new copy of the Person class - that is, it creates a new object.
The left side "john =", is then evaluated after that. It turns john into a reference variable giving it the memory address of the object that was just created on the right side of the same line.
If you want to become a good developer, its important to understand that no computer environment ever works based on philosophic ideals. Computers aren't even that logical - they're really just a big collection of wires that are glued together using basic boolean circuits (mostly NAND and OR).
The word Class comes from Classification (A Category into which something is put), Now we have all heard that a Class is like a Blueprint,but what does this exactly mean ? It means that the Class holds a Description of a particular Category ,(I would like to show the difference between Class , Object and Instance with example using Java and I would request the readers to visualise it like a Story while reading it , and if you are not familiar with java doesn't matter) So let us start with make a Category called HumanBeing , so the Java program will expressed it as follows
class HumanBeing{
/*We will slowly build this category*/
}
Now what attributes does a HumanBeing have in general Name,Age,Height,Weight for now let us limit our self to these four attributes, let us add it to our Category
class HumanBeing{
private String Name;
private int Age;
private float Height;
private float Weight;
/*We still need to add methods*/
}
Now every category has a behaviour for example category Dog has a behaviour to bark,fetch,roll etc... , Similarly our category HumanBeing can also have certain behaviour,for example when we ask our HumanBeing what is your name/age/weight/height? It should give us its name/age/weight/height, so in java we do it as follows
class HumanBeing{
private String Name;
private int Age;
private float Height;
private float Weight;
public HumanBeing(String Name,int Age,float Height,float Weight){
this.Name = Name;
this.Age = Age;
this.Height = Height;
this.Weight = Weight;
}
public String getName(){
return this.Name;
}
public int getAge(){
return this.age;
}
public float getHeight(){
return this.Height;
}
public float getWeight(){
return this.Weight;
}
}
Now we have added behaviour to our category HumanBeing,so we can ask for its name ,age ,height ,weight but whom will you ask these details from , because class HumanBeing is just a category , it is a blueprint for example an Architect makes a blueprint on a paper of the building he wants to build , now we cannot go on live in the blueprint(its description of the building) we can only live in the building once it is built
So here we need to make a humanbeing from our category which we have described above , so how do we do that in Java
class Birth{
public static void main(String [] args){
HumanBeing firstHuman = new HumanBeing("Adam",25,6.2,90);
}
}
Now in the above example we have created our first human being with name age height weight , so what exactly is happening in the above code? . We are Instantiating our category HumanBeing i.e An Object of our class is created
Note : Object and Instance are not Synonyms In some cases it seems like Object and Instance are Synonyms but they are not, I will give both cases
Case 1: Object and Instance seems to be Synonyms
Let me elaborate a bit , when we say HumanBeing firstHuman = new HumanBeing("Adam",25,6.2,90); An Object of our category is created on the heap memory and some address is allocated to it , and firstHuman holds a reference to that address, now this Object is An Object of HumanBeing and also An Instance of HumanBeing.
Here it seems like Objects and Instance are Synonyms,I will repeat myself they are not synonyms
Let Us Resume our Story , we have created our firstHuman , now we can ask his name,age,height,weight , this is how we do it in Java
class Birth{
public static void main(String [] args){
HumanBeing firstHuman = new HumanBeing("Adam",25,6.2,90);
System.out.println(firstHuman.getName());
System.out.println(firstHuman.getAge());
...
...
}
}
so we have first human being and lets move feather by give our first human being some qualification ,let's make him a Doctor , so we need a category called Doctor and give our Doctor some behaviour ,so in java we do as follows
class Doctor extends HumanBeing{
public Doctor(String Name,int Age,float Height,float Weight){
super(Name,Age,Height,Weight);
}
public void doOperation(){
/* Do some Operation*/
}
public void doConsultation(){
/* Do so Consultation*/
}
}
Here we have used the concept of Inheritance which is bringing some reusability in the code , Every Doctor will always be a HumanBeing first , so A Doctor will have Name,Age,Weight,Height which will be Inherited from HumanBeing instead of writing it again , note that we have just written a description of a doctor we have not yet created one , so let us create a Doctor in our class Birth
class Birth{
public static void main(String [] args){
Doctor firstDoctor = new Doctor("Strange",40,6,80);
.......
.......
/*Assume some method calls , use of behaviour*/
.......
.......
}
}
Case 2: Object and Instance are not Synonyms
In the above code we can visualise that we are Instantiating our category Doctor and bringing it to life i.e we are simply creating an Object of the category Doctor , As we already know Object are created on Heap Memory and firstDoctor holds a reference to that Object on the heap ;
This particular Object firstDoctor is as follows (please note firstDoctor holds a reference to the object , it is not the object itself)
firstDoctor is An Object of class Doctor And An Instance of A class Doctor
firstDoctor is Not An Object of class HumanBeing But An Instance of class HumanBeing
So a particular Object can be an instance to a particular class but it need not be an object of that given class
Conclusion:
An Object is said to be an Instance of a particular Category if it satisfies all the characteristic of that particular Category
Real world example will be as follows , we are first born as Humans so image us as Object of Human , now when we grow up we take up responsibilities and learn new skills and play different roles in life example Son, brother, a daughter, father ,mother now What are we actually?We can say that we are Objects of Human But Instances of Brother,daughter,...,etc
I hope this helps
Thank You
Objects are things in memory while instances are things that reference to them. In the above pic:
std(instance) -> Student Object (right)
std1(instance) -> Student Object (left)
std2(instance) -> Student Object (left)
std3(instance) -> no object (null)
An object is an instance of a class (for class based languages).
I think this is the simplest explanation I can come up with.
A class defines an object. You can go even further in many languages and say an interface defines common attributes and methods between objects.
An object is something that can represent something in the real world. When you want the object to actually represent something in the real world that object must be instantiated. Instantiation means you must define the characteristics (attributes) of this specific object, usually through a constructor.
Once you have defined these characteristics you now have an instance of an object.
Hope this clears things up.
"A class describes a set of objects called its instances." - The Xerox learning Research Group, "The Smalltalk-80 System", Byte Magazine Volume 06 Number 08, p39, 1981.
What is an Object ?
An object is an instance of a class. Object can best be understood by finding real world examples around you. You desk, your laptop, your car all are good real world examples of an object.
Real world object share two characteristics, they all have state and behaviour. Humans are also a good example of an object, We humans have state/attributes - name, height, weight and behavior - walk, run, talk, sleep, code :P.
What is a Class ?
A class is a blueprint or a template that describes the details of an object. These details are viz
name
attributes/state
operations/methods
class Car
{
int speed = 0;
int gear = 1;
void changeGear(int newGear)
{
gear = newGear;
}
void speedUp(int increment)
{
speed = speed + increment;
}
void applyBrakes(int decrement)
{
speed = speed - decrement;
}
}
Consider the above example, the fields speed and gear will represent the state of the object, and methods changeGear, speedUp and applyBrakes define the behaviour of the Car object with the outside world.
References:
What is an Object ?
What is a Class ?
I think that it is important to point out that there are generally two things. The blueprint and the copies. People tend to name these different things; classes, objects, instances are just some of the names that people use for them. The important thing is that there is the blueprint and copies of it - regardless of the names for them. If you already have the understanding for these two, just avoid the other things that are confusing you.
Lets compare apples to apples. We all know what an apple is. What it looks like. What it tastes like. That is a class. It is the definition of a thing. It is what we know about a thing.
Now go find an apple. That is an instance. We can see it. We can taste it. We can do things with it. It is what we have.
Class = What we know about something. A definition.
Object/Instance = Something that fits that definition that we have and can do things with.
In some cases, the term "object" may be used to describe an instance, but in other cases it's used to describe a reference to an instance. The term "instance" only refers to the actual instance.
For example, a List may be described as a collection of objects, but what it actually holds are references to object instances.
I have always liked the idea that equals the definition of a class as that of an "Abstract Data Type". That is, when you defined a class you're are defining a new type of "something", his data type representation, in terms of primitives and other "somethings", and his behavior in terms of functions and/or methods. (Sorry for the generality and formalism)
Whenever you defined a class you open a new possibility for defining certain entities with its properties and behavior, when you instantiate and/or create a particular object out of it you're actually materializing that possibility.
Sometimes the terms object and instances are interchangeable. Some OOP purists will maintain that everything is an object, I will not complain, but in the real OOP world, we developers use two concepts:
Class: Abstract Data Type sample from which you can derive other ADT and create objects.
Objects: Also called instances, represents particular examples of the data structures and functions represented by a given Abstract Data Type.
Object Oriented Programming is a system metaphor that helps you organize the knowledge your program needs to handle, in a way that will make it easier for you to develop your program. When you choose to program using OOP you pick up your OOP-Googles, and you decide that you will see the problem of the real world as many objects collaborating between themselves, by sending messages. Instead of seeing a Guy driving a Car you see a Guy sending a message to the car indicating what he wants the car to do. The car is a big object, and will respond to that message by sending a message to it's engine or it's wheel to be able to respond properly to what the Driver told him to do in the message, etc...
After you've created your system metaphor, and you are seeing all the reality as objects sending messages, you decide to put all the things your are seeing that are relevant to your problem domain in the PC. There you notice that there are a lot of Guys driving different cards, and it's senseless to program the behavior of each one of them separately because they all behave in the same way... So you can say two things:
All those guys behave in the same way, so I'll create a class called
Driver that will specify who all the Drivers in the world behave,
because they all behave in the same way. (And your are using class based OOP)
Or your could say Hey! The second Driver behaves in the same way as the first Driver, except he likes going a little faster. And the third Driver behaves in the same way as the first Driver, except he likes zigzagging when he drives. (And you use prototype based OOP).
Then you start putting in the computer the information of how all the Drivers behave (or how the first driver behave, and how the second and third differ from that one), and after a while you have your program, and you use the code to create three drivers that are the model you are using inside that PC to refeer to the drivers you saw in the real world. Those 3 drivers that you created inside the PC are instances of either the prototype ( actually the first one is the prototype, the first one might be the prototype himself depending on how you model things) or the class that you created.
The difference between instance and object is that object is the metaphor you use in the real world. You choose to see the guy and the car as objects (It would be incorrect to say that you see them as instances) collaborating between themselves. And then you use it as inspiration to create your code. The instance only exists in your program, after you've created the prototype or the class. The "objects" exist outside the PC because its the mapping you use to unite the real world with the program. It unites the Guy with the instance of Driver you created in the PC. So object and instance are extremely related, but they are not exactly the same (an instance is a "leg" of an object in the program, and the other "leg" is in the real world).
I guess the best answer has already been given away.
Classes are blueprints, and objects are buildings or examples of that blueprint did the trick for me as well.
Sometimes, I'd like to think that classes are templates (like in MS Word), while objects are the documents that use the template.
Extending one of the earlier given examples in this thread...
Consider a scenario - There is a requirement that 5 houses need to be built in a neighbourhood for residential purposes. All 5 houses share a common construction architecture.
The construction architecture is a class.
House is an object.
Each house with people staying in it is an instance.

Object Oriented Design Interview [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.
Any advice on solving this problem?
Well, here's one good one that I came up with - utilizing OOP overriding, subclass and superclass:
namespace Animals{
// base class Animal
class Animal{
public void eat(Food f){
}
}
class Carnivore extends Animal{
public void eat(Meat f){
}
}
class Herbivore extends Animal{
public void eat(Plant f){
}
}
class Omnivore extends Animal{
public void eat(Food f){
}
}
}
namespace Food{
// base class Food
class Food{
}
class Meat extends Food{
}
class Plant extends Food{
}
}
I create subclasses Herbivore, Carnivore and Omnivore from the superclass Animal and override the eat method with the type of food that it can actually eat.
So:
Plant grass = new Plant();
Herbivore deer = new Herbivore();
deer.eat(grass); // ok
Plant grass2 = new Plant();
Carnivore tiger = new Carnivore();
tiger.eat(grass2); // not ok.
Meat deer2 = new Meat();
tiger.eat(deer2); // ok
Well, the final problem is that, when you specify that deer is a Herbivore, you can't make it a Meat for tiger to eat. However at the end of the day, this should be sufficient for solving the interview problem whilst not putting the interviewer to sleep.
There's a wonderful poster for the Liskov Substitution Principle that says, "If it looks like a duck, quacks like a duck, but needs batteries, you've probably got the wrong abstraction." And that's the quick answer - some of the objects can be both animals and food, so unless you're willing to go the route of multiple inheritance, then the classification schema is all wrong.
Once you've cleared that hurdle, the rest is open-ended, and you can bring in other design principles. For instance, you could add an IEdible interface that allows objects to be consumed. You might go aspect-oriented, and add decorators for carnivore and herbivore, and that would allow consumption of only the right class of objects.
The point is to be able to think on your feet, to see and explain various aspects of a problem, and to communicate well. And perhaps not to get stuck on a "one right answer" limitation.
I'd tell him to scratch that. It's a horrible abstraction. Not to mention we're not given any context. Abstractions don't come out of thin air, or out of an "idea" of what's "right". Show me what problem are you trying to solve first, so we can evaluate this abstraction.
If no context is provided, then I'll just assume/make-up my own: you want some types of objects to be able to eat other types of objects. Nothing more, nothing less.
Make an Eatable interface (or you can call it Food, if you want), and since we have no context what so ever, I'll assume it's a toy console program, that just prints:
<X> ate <Y>
so all we need for this interface is a getFoodName() method.
For error checking, you can create a bunch of isXFoodType methods, for instance, isGrassFoodType(), isMeatFoodType(), etc. The Cow's implementation of Eat(Eatable e) would check for isGrassFoodType(), and when fails, prints:
"Cow can't eat " + e.getFoodName()
Alan Kay, who coined the term "object-oriented programming", has said "OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things".
Trying to fix this "problem" in the data model sounds to me like the opposite of late-binding: why do you need the compiler to enforce this? I wouldn't worry about changing the model at all. If you're passed something you can't eat, you throw an exception -- just like in real life, pretty much!
Food should be an interface, therefore Plant and Animal could be Food too.
abstract Animal class should have eat method that take Food as parameter.
subclasses of Animal: Carnivore, Herbivore and Omnivore should have their own version of eat.
For example for Carnivore:
private void eat(Food food)
{
if(food instanceof Animal)
{
happilyEat();
}
else
{
sniff&TurnAway();
}
}
The Problems solved.
But for a better design, Carnivore, Herbivore and Omnivore should be interfaces too, as they are not the proper way of tagging the animals.
This is easy with Generics in C# btw:
public class Food
{
}
public abstract class Animal<T> : Meat where T:Food
{
public abstract void Eat(T food);
}
public class Herbivore : Animal<Plant>
{
public override void Eat(Plant food)
{
Console.WriteLine("Herbivore eats plants.");
}
}
public class Omnivore : Animal<Food>
{
public override void Eat(Food food)
{
Console.WriteLine("Omnivore eats food.");
}
}
public class Carnivore : Animal<Meat>
{
public override void Eat(Meat food)
{
Console.WriteLine("Carnivore eats meat.");
}
}
public class Plant : Food
{
}
public class Meat : Food
{
}
public class Cow : Herbivore
{
}
public class Tiger : Carnivore
{
}
public class Human : Omnivore
{
}
Usage:
var human = new Human();
var tiger = new Tiger();
var cow = new Cow();
var plant = new Plant();
human.Eat(cow);
tiger.Eat(human);
cow.Eat(tiger); // this doesn't compile
tiger.Eat(plant); // neither does this
Here's some thoughts on that interview question:
I agree with Cylon Cat: This kind of abstraction doesn't work well without multiple inheritance (even if it's Java-like interfaces.)
I would create two forms of inheritance:
Animal:
Carnivore
Herbivore
Food:
Meat
Vegetable
The "eat" method of the two kinds of animals (I'm ignoring omnivores, insectivores, and many other kinds) would be specialized for the different kinds of food. If we're using a language like Java, then Food would be an interface.
Any animal is food, any vegetable is food. And in fact a tiger can be eaten by a cow. (The prion disease scrapie is spread by feeding infected sheep neural tissue to uninfected sheep.)
You could have a hierarchy of species, ala Linnaeus, both animal and vegetable. Each species is a Singleton, and it has a List<Species> that records its typical diet. Ditch the Food hierarchy entirely, it only confuses things.
And, if your only problem is recording diet for each species, then the multiple Species classes are unnecessary. Just have a single Species class with the species name as one instance variable and the List<Species> as another.
There's no one best solution. You might want to make this a community wiki, as that's generally the accepted practice for subjective questions.
I'd think about what actually would make the best parent class for the hierarchies, and try to figure out what "best" means in that context.
Everything there are Things, which could have a Name attribute. But everything there at some level is Food; if it can eat something, something can eat it. I might make Food the parent class, and give it a method that returns a boolean to check if the parameter object can eat the current object.
So,
class Food {
boolean canBeEatenBy(Food hungryObject)
String name
}
That seems the simplest class hierarchy that fits everything I might need on a first pass?
That said, the important part in most interview questions is the feel you get for the interviewee, not so much the exact answer that they give.
Double dispatch, perhaps?
If you expect the system to get very big I would suggest subclassing plant/meat and herbivore/carnivore/omnivore.
Ensure the system has a standard interface for all plant/animals called getFoodName() and getFoodType(), you could enforce this by creating a parent class for plants/animals called species.
The problem I would see with the subclassing plant/meat and carnivore/herbivore is that a meerkat is carnivore but it likely can't eat a rhino(there may be a better example), so some restrictions are needed beyond "I eat meat, you eat plants".
If it wasn't going to get incredibly big and you wanted to be neurotic about it, you could store static enums of allowable foods for each subclass of animal. So tiger could store deer, antelope etc.