Learning the Basics of Object-Oriented Programming
Older, procedural-driven languages were difficult on developers in terms of code organization. As projects in these languages grew, it became hard to manage the source code. Larger projects could be split up into different source files, but many times the variable or procedure declarations would collide if they had similar names (which is just one example of the problems that the lack of organization produced). Programmers found they had to name their constructs uniquely to avoid collisions, which meant the variable and procedure names got longer and longer. Having procedure names such as StockItemSaveMonthlyPaymentToDatabase certainly didn’t help make the code more readable.Part of the issue was simply finding things in a large project. As a natural step, developers began putting procedures that handled similar functions together, sometimes in a single source module. Therefore, all the reports might reside together, or all of the routines handling one type of data might reside together.The object-oriented programming approach was developed, in part, to allow developers to organize the code by grouping together code constructs that handle similar functions. In fact, the object-oriented programming methodology forces the developer into grouping code in a natural way and into doing so from the beginning of the coding process. Programmers new to this approach might find this methodology difficult at first because they often can’t simply jump into their editors and start writing lines of code. Instead, before you start coding, you must plan how you’ll organize the code and group it into units and, to some extent, how these units will interact.
What Are Classes and Objects, Anyway?
The basic grouping mechanism in an object-oriented programming approach is known as a class. A class is a grouped collection of code and data that models something in life—either a concrete item or a concept. For example, if you’re going to write a program that collects information about people (a human resources application, perhaps), then you’ll probably create a class in your application that models a person and another class that models a group of people (such as all those in a department or all those managed by one supervisor). If your application instead tracks information for a library, then you’ll most likely create classes to model books, magazines, videotapes, CDs, and anything else people can check out of the library. If your program is going to track baseball games, then it would be natural to create classes for players, pitchers, games, teams, leagues, and seasons.As you can see, the minute you describe a program, even with a single sentence (“a program to track baseball games”), the object-oriented approach asks you to begin modeling the real or theoretical concepts of your program into distinct classes.One way to think of a class is as a recipe to create something. An object, on the other hand, is an actual something. In other words, if a class is a recipe for a cake, then an object is the cake you create from the recipe. You can use the recipe to create many different cakes, and the cakes can be the same (the same flavor, the same frosting, the same number of tiers), or they can be different. Extending the analogy into the programming world, the class is the recipe, and it doesn’t maintain any real presence in memory—all the class can do for you is create one or more instances of whatever it models. These instances are called objects. Each object has its own memory space and is independent. So, if you have a BaseballPlayer class, then you can create one, two, or 25 instances of that class to represent all the players on a team. You might also have a BaseballTeam class that contains the 25 BaseballPlayer instances. You could then have 30 instances of the BaseballTeam class, each representing a different team in a league. These 30 BaseballTeam instances might be stored in two instances of the BaseballLeague class, representing the American and National Leagues (assuming major league baseball players are being modeled). Notice how the organization of the classes and objects model the relationship of these constructs in “real life.”
Why Object-Oriented Programming Is Valuable
This object organization is a powerful concept in that it’s both self-documenting and extendable. It would be easy to draw a graphical representation of the classes previously described; people create such graphical representations all the time— the official name for such a drawing is a UML class diagram. (UML stands for Unified Modeling Language.) In addition, the relationship of the classes makes it easy to know where to “put things” when the developer adds functionality to the program. Suppose version 2.0 of the baseball program has to also model front-office personnel (to store their contract information, for example). It’s easy to see that you can create a FrontOfficeMember class, and you can place instances of that class where they belong—as part of the BaseballTeam class (perhaps now renaming it to something more appropriate such as BaseballOrganization). If the program has to track some new advanced statistic for each player, it’s evident that this new statistic will become a member of the BaseballPlayer class so that every instance of this object has a place to store this statistic.One other important thing to know about classes is that their definitions can be hierarchical in nature, which is to say that you can create a class by first starting off with another class and then extending the functionality of that base class to create something new. When you do this, the base class is called the ancestor, and the new class is called the descendant. You can also say that the new class is a subclass of the base class. The .NET class hierarchy is a giant family tree in which you can trace every class back to a single ancestor. That “patient zero” ancestor is the class that has the (somewhat unfortunate) name of Object.Subclassing gives you a powerful way to share functionality between classes that are somewhat, but not entirely, similar. Getting back to the baseball example, the program has to represent both pitchers and hitters. Pitchers and hitters share many common traits—for instance, they both belong to teams, they both have uniform numbers, and they both have a height, weight, age, and birthplace. Many of them went to school and played baseball there, which is another piece of information you’ll want to store.However, hitters and pitchers also contain many differences that you need to keep distinct. Pitchers have a separate statistical set than hitters; for pitchers, the program has to keep track of innings pitched, earned run average, and number of starts, wins, and losses (among other statistics). For hitters, relevant statistics include batting average and number of hits, walks, and strikeouts.
You can easily model this relationship by using the subclassing ability of an object-oriented language. You could model these constructs by creating an ancestor class named BaseballPlayer and creating two subclasses from this class named BaseballOffensivePlayer and BaseballPitcher. The common pieces of information such as height, weight, age, and school would reside in the ancestor class, and the specific pieces of information unique to hitters and pitchers would reside in the appropriate subclass.You’ll start looking at VB classes to see examples of all these concepts soon, but you have one stop to make first—the .NET Framework.