View this PageEdit this PageAttachments to this PageHistory of this PageHomeRecent ChangesSearch the SwikiHelp Guide
Hotspots: Admin Pages | Turn-in Site |
Current Links: Cases Final Project Summer 2007

Discussion 1 - Jack Gruendler

Source: Encapsulation and Inheritance in Object-Oriented Programming Languages, Alan Snyder, OOPSLA 1986.

Two major defining features of object-oriented programming are encapsulation and inheritance. Different languages implement these concepts in different ways, because there are tradeoffs between them.

The idea behind encapsulation is that the object's data is hidden and that it provides a certain interface, so that client programmers don't have to care about the implementation – it can be changed without breaking downstream code.

The idea behind inheritance is that instead of creating a new class from scratch, it can be a subclasses of a previously-defined class (its "parent"). In order for inheritance to be useful, the operations and/or data in the parent class must be available for use by the child class, and possibly also by users of the child class.

This creates a problem, because making the implementation of the parent class accessible to its children necessarily violates the principle of encapsulation. The effect of inheritance means that every class actually has two external interfaces – one for things that use the class, and another for things that inherit from the class.

There are a few choices for languages to make here: they can allow the child class to access the parent's instance variables (such as in Smalltalk and Objective-C), but this restricts the parent class from changing its instance variables. On the other hand, languages like C++ and CommonObjects (object-oriented Lisp) instead only allow access to the parent's variables through operations (accessors and modifiers).

Multiple inheritance is another issue. It's a powerful feature, but some languages choose to disallow it because it can cause problems. For example, if several parent classes define an method, there is no easy way to determine which one(s) should be executed when called on the child class. This is further complicated because both parents might have a common parent which originally implemented the method, but one might have overridden it. Moreover, even if both implementations of the method are the same, if it has side effects it can still cause problems because some languages call both inherited copies!

In summary, the choices the language makes in balancing encapsulation with inheritance determines what features the language supports (e.g. multiple inheritance, ability to access parent instance variables, etc.), which in turn affects the strategies programmers take in using it.

Andrew Calvin's discussion mentions the complexity of languages, but doesn't explore the reasons why they got that way. Based on Snyder's analysis, it seems that the complexity of syntax is directly related to the choices the language's designer made regarding encapsulation and inheritance. For example, the reason Smalltalk is simple is that making everything an object forces everything to use encapsulation. Similarly, C++'s complex syntax and complicated process of overloading methods is a necessary consequence of the decision to use multiple inheritance.

Links to this Page