Object Oriented Programming, at its root, is all about combining the data
structures of a program with the code to work on those data structures.
This
encapsulation of code and data allows programmers to concentrate on the
flow and relationships of data in a program. And programs are all about data:
without data, there is nothing for the program to do. Without data, the most
efficient sorting algorithm is no faster than the worst.
To get an object to
do something with its data, we have to invoke a subroutine that is part of the
object. To make this convenient--and less prone to keyboard error--Object
Oriented languages handle determining the correct subroutine for you. And the
resulting action is known by several phrases, such as "invoking an instance
method" or "sending a message to an object".
So, for example, in Objective C
you could make yourself a Dog class:
@interface Dog : NSObject
-
(void)Bark;
@end
What that means is, any new Dog object can be sent
a Bark message. (There's no data involved--no arguments, no instance
variables--so presumably Bark is a method that has side
effects.)
Similarly, in Java, we can do the same thing, just with
different syntax:
public class Dog {
void Bark() {
}
}
There's two differences in Java: first, there's no obvious
ancestor class--the compiler will automatically make our class depend on
java.lang.Object. Second, this is actually the implementation, and our
Bark() method is far from finished--it doesn't actually do anything. (You can't
tell in the Objective C code earlier, because I left out the
implementation.)
So, we haven't actually done any serious object modelling,
and we already have inheritance. Java, Objective C and SmallTalk all require all
classes inherit from a single ancestor class, java.lang.Object,
NSObject and Object respectively.
(I couldn't find an
explicit claim for that for SmallTalk, but you create new classes by sending a
message to an existing class--starting from Object. By induction, therefore,
tree hierarchy (single root), not a forest (C++).)
This makes it very easy
to support collections: all the collection has to recognize is the root object,
and it will still be able to send messages to every element in a collection. In
Objective C:
NSArray *dogs=[NSArray
arrayWithObjects:myDog,yourDog,hisDog,nil];
[dogs
makeObjectsPerformSelector:@selector(Bark:)];
The Array class doesn't
need to know what it's holding, and yet you can ask it to make all the dogs
bark. (An Objective C "selector" is just the name of a method, in a canonical
form for the computer to use. By having special syntax for it, the compiler can
typo-proof it before you run it.)
But what if you get a cat? There are
things cats and dogs have in common--they're mammals, and we keep some as
pets.
That first one: they are--we call that an "is-a" relationship.
Anything something "is" will typically be a candidate for being made its own
class. A car is a vehicle; so is a bicycle. A house is a building, so is a
stadium.
public class FurryMammal {
Colour
FurColour();
}
public class Dog extends FurryMammal {
void
Bark() { ... }
boolean Fetch(java.lang.Object what) { ...
}
}
public class Cat extends FurryMammal {
void Meow() { ...
}
boolean ShredCurtains() { ... }
}
So, Cat and Dog are
both FurryMammals. A Dog can Bark, and you can ask it to Fetch an object. (It
will say if it did or not.) Cat, on the other hand, can Meow and
ShredCurtains.
Because of inheritance from FurryMammal, both Cat and Dog
will answer the FurColour message--you don't have to write additional code for
that, you inherited that method (and any data) from your superclass.
(These
examples are to illustrate the concepts only, they are not an example of good
practice in either language.)
That's the most important two: inheritance and
encapsulation. You can find both of them in Simula 67, the accepted ultimate
root class of Object Oriented Programming.
Some will say "hiding" and
"protection" (private, protected keywords) are important. But that actually
requires a huge conversation about trust: Perl, for example, went with "we're
all just trying to code here", and has no object member security features--just
an agreement that if you do something dumb, you pay the consequences. (Some
might say your consequence is having to maintain Perl code.)
Others will
mention "polymorphism": the ability to have different subroutines with the same
name that take different argument types. It does tend to flow from the object
design, but I don't consider it fundamental.
The C++ people will probably go
on about "templates", because they help solve a problem central to their
language environment.
Getting everyone to agree on just what an Object
Oriented language is... a lot like trying to send a herd: message to an array of
Cats.
[ Reply to This | Parent | # ]
|