Thursday, September 11, 2008

Three Questions about Object Oriented Basics

The basics concepts that object oriented programming deals with are encapsulation, inheritance and polymorphism. I don't intend to fully explain these concepts here. Rather, I intend to answer a recently-received, specific question about each.

Encapsulation
Do you have an example of interacting with something public but not private?

Encapsulation is, of course, the idea of hiding implementation.

As far as an example goes, here is a contrived one. Suppose that we have a class describing a person.
public class Person { ... }
Suppose also that we need to be able to get the person's name in three different ways -- full name, first name and last name. We create a public set of methods to retrieve these values.
public class Person
{
public String GetFullName() { ... }
public String GetFirstName() { ... }
public String GetLastName() {... }
}
The class encapsulates the data behind these methods. From the perspective of using this class, we don't care how that data is stored.
Person person = new Person( ... );

... person.GetFullName() ...
... person.GetFirstName() ...
... person.GetLastName() ...
From the perspective of implementing this class, we have several choices for how to store this information.

We could store the full name in a single variable and then return that value for the GetFullName method while parsing out the first and last name for the other two methods.

Assuming that we have a Split method in the String class that returns a string array by dividing up the string using a delimiter:
public class String
{
String[] Split(Char delimiter) { ... }
}
We can write the Person implementation like this:
public class Person
{
private String fullName;

public String GetFullName() { return fullName; }
public String GetFirstName() { return fullName.Split(' ')[0]; }
public String GetLastName() { return fullName.Split(' ')[1]; }
}
As a different alternative, we could store the first and last names as separate variables and return the individual values for the GetFirstName and GetLastName methods while returning a concatenated value for the GetFullName method.
public class Person
{
private String firstName;
private String lastName;

public GetFullName() { return firstName + ' ' + lastName; }
public GetFirstName() { return firstName; }
public GetLastName() { return lastName; }
}
We could store the first and last names in a dictionary and retrieve the parts as needed.
public class Person
{
private Dictionary names;

public GetFullName() { return names["first"] + ' ' names["last"]; }
public GetFirstName() { return names["first"]; }
public GetLastName() { return names["last"]; }
}
There are several other alternatives, but just for sake of the example, here's one more.

We could store the names in a string array where the first name is in the first position of the array and the last name is in the last position of the array.

Assuming that we have a static Join method in the String class that takes all the members of a string array and joins them together with a specified delimiter:
public class String
{
public static String Join(String[] array, String delimiter) { ... }
}
We can write the implementation like this:
public class Person
{
private String[] names;

public String GetFullName() { return String.Join(names, " "); }
public String GetFirstName() { return names[0]; }
public String GetLastName() { return names[names.Length - 1]; }
}
This final example has the advantage that any number of middle names can be included.

Of course, in all of these examples, there would need to be a constructor or setter method that initializes the private data members and appropriate error handling would also need to be added.

Inheritance
How do you find out the superclasses and subclasses of a given class?

The easy answer is to use an object browser. Depending on which language you use, there are probably different tools that can be used. The additional answer is to read the documentation (aka. help files) that come with the framework or library that you are using. And of course, you can search the source code.

It would probably be helpful to flesh out this answer on a language by language case.

Polymorphism
What is polymorphism?

The concept of polymorphism is to use the same name for a method but with different parameters and/or parameter types.

The place that I've seen this used the most is in data structure or other low-level classes such as collections and input/output related functionality. A collection class will have a method to add another object to the collection. The method might be called Add. There will then be several methods called Add, but a different parameter type will be used for each method.
public class Collection
{
public void Add(int object) { ... }
public void Add(long object} { ... }
public void Add(string object} { ... }
...
}
For output, there is the idea of displaying a data value in human-readable format.
public class Out
{
public void Write(int object) { ... }
public void Write(long object) { ... }
public void Write(string object) { ... }
...
}
Other low-level classes might deal with things like communication protocols or database connections. In some cases, the setup is easy, so there is only one or two parameters. For other cases, the setup is more complex, so there is a method by the same name that takes more parameters.
public class Database
{
public void Connect(string databaseName) { ... }
public void Connect(string databaseName,
string userName, string password) { ... }
public void Connect(string databaseName,
ISecurityManger securityManger) { ... }
...
}
With polymorphism, the compiler looks at the parameter types to determine which method to use.

No comments: