Many people are teaching programmers object oriented programming by thinking about real world objects.
A chicken and a sparrow are both birds, so think about creating a bird class, and deriving 2 subclasses.
A sparrow definitely cannot cluck, so only the chicken gets a cluck method.
At this point, the teacher, who likely has never seen a chicken without breading and cole slaw, tries to figure out if chickens can fly.
Since I grew up with a friend who raised chickens, I will give both a fly method, but the chickens will print 'flutter'.
This gives us:
abstract class Bird
{
abstract void Fly();
bool hasFeathers() { return true; }
}
public class Sparrow : Bird
{
override void Fly()
{
print('Fly');
}
}
public class Chicken : Bird
{
override void Fly()
{
print('Flutter');
}
void Cluck()
{
print (‘Cluck’);
}
}
void SomeMethod()
{
Chicken chicken = new Chicken();
Sparrow sparrow = new Sparrow();
print ('Do sparrows have feathers');
print sparrow.hasFeathers();
print ('Can sparrows fly?');
print ('Sparrows ');
print sparrows.Fly();
print ('Do chickens have feathers');
print chicken.hasFeathers();
print ('Can chickens fly?');
print ('Chickens ');
print chicken.Fly();
}
What could be easier? This teaches a student how to categorize based on logical real world concepts and how to implement inheritance in C++ style languages.
There is a huge problem with this though. We don't want new programmers to categorize based on logical real world concepts. Often times, logical real world concepts is a good place for production programmers to start dividing up large problems. But students at this level aren't ready to work on problems 1/10th that size.
Consider the code:
void SomeMethod2()
{
print ('Do sparrows have feathers? True');
print ('Can sparrows fly? Sparrows fly');
print ('Do chickens have feathers? True');
print ('Can chickens fly? Chickens flutter');
}
Aside from being too trivial to use to teach programmers, SomeMethod2() is better in all possible ways (extensible, readable, maintainable etc). If we wanted to write a non-trivial program to track various attributes about birds, we likely would create a relational database.
This is an extremely dangerous, wrong lesson that programmers will need to unlearn later. Some programmers simply don't unlearn this, just cannot stop classifying, and probably would have been happier as taxonomists in the biology department. Legal secretaries are users, so why not derive a class from them for users - heck why not even derive them from a secretary class? U.S. Dollars are money, Wednesday is a weekday. When the only tool you have is a hammer, every problem looks like a nail. There is no end to the number of real world relationships that the tool of object oriented programming seems to apply to. Maybe someone can teach them Prolog.
The reason we have object oriented programs is not to classify but to create good coupling and cohesion in ways easy for human beings to understand. Bad chicken code completely ignores coupling and cohesion, the above example (and most bad chicken code) only suffers from bad cohesion, but throw a bad chicken coder at a large enough problem, and you get coupling issues as well, since they are thinking in terms of classification, not relationships, abstraction or data flow.
Ian Griffiths (http://www.interact-sw.co.uk/iangblog/2005/09/26/extensionmethods) comments on inheritance and says “It conflates two very important but really rather different concepts: reuse and polymorphism”. Now we are teaching our students to use inheritance to define relationships and classifications rather than reuse or polymorphism.
I was writing programs complicated enough to justify object oriented code long before I learned object oriented programming, and I am not sure how I would go about teaching a new programmer now. You cannot completely ignore classes if you teach using Java or similar languages, and teaching Pascal (how I learned) is just too outdated. Maybe it would be best to gloss over the class keyword until programmers are writing 1,000 line programs (1 class, several methods), and then show them how much easier programming is if you break code up based on related functionality. That way they understand why and when to use different classes at the same time they learn how.