2 008
INHERITANCE CASE-STUDY OF OOP
PRINCE http://www.tch2get.blogspot.com 1/17/2008
INDEX INTRODUCTION •
What is inheritance?
•
Concept of inheritance
•
Subclass, subtypes & substitutability
•
Subtypes & strong typing
FORMS OF INHERITANCE •
Specialization
•
Specification
•
Construction
•
Generalization
•
Extension
•
Limitation
•
Combination
NEED OF INHERITANCE APPLICATION OF INHERITANCE •
Specialization
•
Overriding
•
Code re-use
•
Limitation & Alternatives
2 | Page
CONSTRAINTS OF INHERITANCEBASED DESIGN •
Singleness
•
Static
•
Visibility
3 | Page
RULES OF INHERITANCE BENEFIT OF INHERITANCE •
Software Reusability
•
Code sharing
•
Consistency of inheritance
•
Software component
•
Rapid prototyping
•
Polymorphism & framework
•
Information hiding
COST OF INHERITANCE •
Execution speed
•
Program size
•
Message passing overhead
•
Program complexity
4 | Page
5 | Page
INHERITANCE INTRODUCTION The major change occurred for the VB programmers was when Microsoft announced the launch of their new VB.NET to become the best successor for our most favorite programming language Visual Basic. VB lacked something powerful, which is INHERITENCE, so Microsoft decided to implement in VB.NET. Every time we a new form in our applications we create a new instance of the system. Windows. Forms. Form, class changes its properties to suit our needs .Place some control and our forms are ready for our use. As we know, by placing some control on to a new form, we extend the form class to NEWFORM1 means that we have created a new class with a new name NEWFORM1. Our new form is a class; we can extend any class due to inheritance supported in .NET So from this we can conclude that we can design the base form and use the base form design in all our forms. Now we can use the child forms in the way we desired. We can do our child forms; over ride the functionality of the base form within the child form itself (i.e. using shadows keyword in our function in the child form) we can add custom properties to our base form and set them in the child forms (for controlling the controls which originally does not exists in the parent form) and everything which we want
6 | Page
What Is Inheritance? Different kinds of objects often have a certain amount in common with each other. Mountain bikes, road bikes and tandem bikes, for example, all share the characteristics of bicycles (current speed, current pedal cadence, current gear). Yet each also defines additional features that make them different: tandem bicycles have two seats and two sets of handle bars; road bikes have drop handlebars; some mountain bikes have an additional chain ring, giving them a lower gear ratio. Object-oriented programming allows classes to inherit commonly used state and behavior from other classes. In this example, BICYCLES now becomes the SUPER CLASS of mountain bikes, road bike and tandem bikes. In the java programming language, each class is allowed to have one direct super class, and each super class has the potential for an unlimited number of subclasses. In object-oriented programming, inheritance is a way to form new classes (instances of which are called objects) using classes that have already been defined. The new classes, known as derived classes, take over (or inherit) attribute and behavior of the preexisting classes, which are referred to as base classes (or ancestor classes). It is intended to help reuse existing code with little or no modification. Inheritance provides the support for representation by Categorization in computer languages. Categorization is a powerful mechanism number of information processing, crucial to human learning by means of generalization (what is known about specific entities is applied to a wider group given 7 | Page
a belongs relation can be established) and cognitive economy (less information needs to be stored about each specific entity, only its particularities). Inheritance is also sometimes called generalization, because the is-a relationships represent a hierarchy between classes of objects. For instance, a "fruit" is a generalization of "apple", "orange", "mango" and many others. One can consider fruit to be an abstraction of apple, orange, etc. Conversely, since apples are fruit (i.e., an apple is-a fruit), apples may naturally inherit all the properties common to all fruit, such as being a fleshy container for the seed of a plant. Inheritance therefore has another view, a dual, called polymorphism, which describes many pieces of code being controlled by shared control code. An advantage of inheritance is that modules with sufficiently similar interfaces can share a lot of code, reducing the complexity of the Inheritance is typically accomplished either by overriding (replacing) one or more methods exposed by ancestor, or by adding new methods to those exposed by an ancestor. Complex inheritance, or inheritance used within a design that is not sufficiently mature, may lead to the Yo-yo problem.
In programming languages INHERITENCE means that the behavior and data associates with child classes are always an extension (that is a large set) of the properties associated with parent classes. Subclasses must have all the properties of the 8 | Page
parent class, and other properties as well. On the other hand, since a child class is more specialized form of parent class, it is also in certain sense, a contradiction of the parent type. This tension between inheritance as expansion inheritance as contradiction is a source for much of the power inherent in the technique, but in the same time it causes much confusion as to its proper employment . Inheritance is always transitive, so that a class can inherit features from super classes many levels away. That is, if class Dog is a subclass of class Mammal, and class Mammal is a subclass Animal, then dog will inherit attributes from both Mammals as well as of Animals. A complicating factor in our intuitive description of inheritance is the fact that subclass can override behavior inheritance from parent classes. For example, the class platypus overrides the reproduction behavior inherited from the class Mammal, since Platypuses lay eggs. Inheritance is a process by which objects of one class acquiesce the properties of object of another class. It supports the Hierarchical classification. For example: The bird robin is the part of class flying birds, which is again a part of class bird. The principle behind this sort of division is that each derived class. Definition: Inheritance Inheritance is the concept that when a class of object is defined, any subclass that is 9 | Page
defined can inherit the definitions of one or more general classes. This means for the programmer that an object in a subclass need not carry its own definition of data and methods that are generic to the class (or classes) of which it is a part. This not only speeds up program development; it also ensures an inherent validity to the defined subclass object (what works and is consistent about the class will also work for the subclass). The simple example in C++ is having a class that inherits a data member from its parent class. class A { public: integer d; }; class B : public A { public: }; The class B in the example does not have any direct data member does it? Yes, it does. It Inherits the data member d from class A. When one class inherits from another, it 10 | P a g e
acquires all of its methods and data. We can then instantiate an object of class B and call into that data member. void func() { B b; b.d = 10; };
CONCEPT OF INHERITANCE DEFINITION (INHERITANCE) : Inheritance is the mechanism, which allows a class A to inherit the properties of class B. We say “A inherits from B”. Objects of class A thus have access to attributes and methods of class B without the need to redefine them. The following definition defines two terms which we are able refer to participating classes when they use inheritance. DEFINITION (SUPER CLASS/SUBCLASS): If class A inherits from class B, then B is called super class of A. A is called subclass of B. Objects of subclass can be used where objects of the corresponding super class are expected. This is due to the fact that the objects of the subclass share the same behavior as the objects of the super class. Super classes are called parent classes. Subclasses may be called child classes or just derived classes. Of course, you can again inherit from a subclass, making this class the super class of the new subclass. This leads to a hierarchy of super 11 | P a g e
class/subclass relationships. If you draw this hierarchy you get an inheritance graph. A common drawing scheme is to use arrowed lines to indicate the inheritance relationship between two classes or objects. The syntax for creating a subclass is simple. At the beginning, use the extend keyword, followed by the name of the class to inherit from: Class Mountain Bike extends Bicycle { // New fields and methods defining a mountain bike would go here }
Bicycle
Mountain bike
Road bike
Tandem bike
12 | P a g e
This gives Mountain Bike all the sane fields and methods as Bicycles, yet allows its code to focus exclusively on the features that make it unique. This makes code for your subclasses easy to read. However, you must take care to properly document the state and behavior that each super class defines, since that code will not appear in the source file of each subclass. SUBCLASS, SUBTYPES SUBSTITUTABILITY
AND
Consider the relationship of the data type associated with a parent class to the data type associated with a derived, or child class. The following arguments can be made: • Instances of the subclass must possess all data areas associated with the parent class. • Instances of the subclass must implement, through inheritance at least (if not explicitly overridden) all functionality defined for the parent class. •
Thus, an instance of a child class can mimic the behavior of the parent class and should be indistinguishable from an instance of the parent class if substituted in a similar situation. The principle of substitutability says that if we have two classes, A and B, such that class B is the subclass of class A (perhaps several times removed), it should be possible to substitute instances of class B for instances of class A in any situation with no observable effect.
13 | P a g e
SUBTYPES AND STRONG TYPING St atically typed languages( such as C++ and Object Pascal) place much more emphasis on the principle of substitutability than do dynamically typed languages tend to characterize object by their behavior. For example, polymorphic function (a function that can take objects of various classes) in statically typed language can ensure a certain level of functionality only by insisting that all arguments be subclasses of a given class. Since in a dynamically typed language arguments are not typed at all, the same requirement would be simply that an argument must be able to respond to a certain set of messages. FORMS OF INHERITANCE Inheritance is used in a variety of ways. In this section we will describe a few of its more common uses. Note that the following list represents general abstract categories and is not intended to be exhaustive. Furthermore, it sometimes happens that two or more description are applicable to a single situation , because some methods in a single class use inheritance in one way while others use it in another.
Specialization: The child class is a special case of the parent class; in other words the child class is a subtype of the parent class.
Sub classing for specialization (sub typing) 14 | P a g e
Probably the most common use of inheritance and sub classing is for specialization. In sub classing for specialization, the new class is a specialized form of the parent class but specifies the specification the parent in all relevant respect. Thus, in this form of principle of substitutability is explicitly upheld. Along with the following category (sub classing for specification) this is the most ideal form of inheritance, and something that a good design should strive for. Example of sub classing for specialization is as follows: A class window provides general windowing operation (moving, resizing, iconification, and so on).A specialized subclass Text Edit Window inherits the window operation and in addition provides facilities that allow the window to display text edit window satisfies all the properties we expect of a window in general (thus, Text Edit Window, window is a subtype of window in addition being a subclass) we recognize this situation as an example of sub classing for specialization.
Specification: The parent class defines behavior that is implemented in the child class but not in the parent class. This is actually a special case of sub classing for specialization; expect that the subclasses are not refinements of an existing type but rather realization of an 15 | P a g e
incomplete abstract specification. In such cases the parent classes sometime known as an abstract specification class.
Sub classing for specification: Another frequent use for inheritance is to guarantee that classes maintain a certain common interface that is, they implement the same method. The parent class can be a combination of implemented operation and operation that are deferred to the child classes. Often, there is no interface change of any sort between the parent class and the child class-the child merely implements behavior described, but not implemented in the parent.
16 | P a g e
Construction: This child class makes use of the behavior provided by the parent class, but is not a subtype of the parent class.
Sub classing for construction: A class often inherits almost all of its desired functionality from a parent class perhaps changing only the name of the method used to interface to the class, or modifying the argument in a certain fashion. This may be true even if the new class and the parent class fail to share the is-a relationship. For example, the small talk class hierarchy implements a generalization of an array called dictionary. A dictionary is collection of key-value pairs, like an array, but the key can be arbitrary values. A symbol table such as might be used in a compiler can be considered a dictionary index by symbol names in which the values have a fixed format. A class symbol table can therefore made a subclass of the class dictionary, with new method defined that are specific to the use as a symbol table.
Generalization: The child class modified or overrides some of the method of the class.
Sub classing for Generalization: Using inheritance to subclass for generalization is, in a certain sense, the opposite of sub classing for specialization. Here, a subclass extends the behavior of 17 | P a g e
the parent class to create more general kind of object. Sub classing for generalization is often applicable when we build on a base of existing classes that we do not wish to modify, or cannot modify. Consider a graphic display system in which a class window has been defined for displaying on a simple back-and-white background. Sub classing for generalization frequently occurred when the overall design is based primarily on data values and secondarily on behavior.
Extension: The child class adds new functionally to the parent class, but does not change any inherited behavior.
Sub classing for extension: While sub classing for generalization modifies or expands on the existing, functionality of an object, sub classing for extension adds totally new abilities. Sub classing for extension can be distinguished from sub classing for generalization in that the latter must override at least one method from the parent and functionality is tied to the existing method of the parent. An example of sub classing for extension is a string set class that inherits from a generic. Set class but is specified for holding string values. Such a class might provide additional for holding string values. Such a class might provide additional for string-related operation-for example, “search by prefix”, which returns a subset of all elements of the set that begin with a certain string value. These operation are meaningful for the subclass, but are not particularly relevant to the parent class. 18 | P a g e
Limitation : The child class restricts the use of some of the behavior inherited from the parent class.
Sub classing for Limitation: Sub classing for limitation occurs when the behavior of the subclass in smaller or more restrictive than the behavior of the parent class. Like sub classing for generalization, sub classing for limitation occurs most frequently when a programmer is building on a base of existing classes that should not or cannot, be modified. For example, an existing class library Provide a doubleended-queue, or deque, data structure. Elements can be added or removed from either end of the deque, but the programmer wishes to write a stack class, enforcing the property that element can be added or remove from only one end of stack.
19 | P a g e
Sub classing for limitation is an explicit contravention of the principle of substitutability, and because it builds subclasses that are not subtypes, it should be avoided whenever possible.
Variance: The child class and parent class are variants of each other, and the class-subclass relationship is arbitrary.
Sub classing for Variance: Sub classing for variance is employed when two or more classes have more similar implementation but do not seem to posses any hierarchical relationship between the abstract concept represent by the classes. The code necessary to control a mouse. For example may be nearly identical to the code require to control a graphic tablet. Conceptually however, there is no reason why class mouse should be made a subclass of class tablet or the other way. One of the two classes is then arbitrarily selected to be the parent, with the common code being inherited by the other and device-specific code being overridden.
Combination: The child class inherits features from more than one parent class. This is multiple inheritance.
Sub classing for Combination: A common situation is a subclass that represents a combination of features from two or more classes. A teaching assistant, For example, may have 20 | P a g e
characteristics of both a teacher and a student, and can therefore logically behave as both. The ability of class to inherit from two or more parent classes is known as multiple inheritances. It is sufficiently subtle and complex.
What is the need of forms Inheritance? So, the biggest question before reading this-What is the need of Forms inheritance. First, we will be coding all the base/common code into Base form (any form from which we want to inherit). Then instead of copying or writing some global functions to change the properties or call methods, etc. to use some functionality of the base form (as we use to do in our earlier languages), we can use form inheritance here. We can inherit the base form where we want to implement the common functionality. As we inherit form all the public/protected functionality of the base form gets merged into child form.
Applications of inheritance There are many different aspects to inheritance. Different uses focus on different properties, such as the external behavior of objects, internal structure of the object, structure of the inheritance hierarchy, or software engineering properties of inheritance.
21 | P a g e
Sometimes it's desirable to distinguish these uses, as it's not necessarily obvious from context.
Specialization One common reason to use inheritance is to create specializations of existing classes or objects. This is often called sub typing when applied to classes. In specialization, the new class or object has data or behavior aspects that are not part of the inherited class. For example, a "Bank Account" class might have data for an "account number", "owner", and "balance". An "Interest Bearing Account" class might inherit "Bank Account" and then add data for "interest rate" and "interest accrued" along with behavior for calculating interest earned. Another form of specialization occurs when a base class specifies that it has a particular behavior but does not actually implement the behavior. Each non-abstract, concrete class which inherits from that abstract class must provide an implementation of that behavior. This providing of actual behavior by a subclass is sometimes known as implementation or reification.
Overriding Many object-oriented programming languages permit a class or object to replace the implementation of an aspect—typically a behavior—that it has inherited. This process is usually called overriding. Overriding introduces a complication: which version of the behavior does an instance of the inherited class use—the one that is part of its own class, or the one from the parent (base) class? The answer varies between programming languages, and some languages provide the ability to indicate that a particular behavior is not to be overridden. 22 | P a g e
Code re-use One of the earliest motivations for using inheritance was to allow a new class to re-use code which already existed in another class. This practice is usually called implementation inheritance. In most quarters, class inheritance for the sole purpose of code re-use has fallen out of favor. The primary concern is that implementation inheritance does not provide any assurance of polymorphic substitutability— an instance of the re-using class cannot necessarily be substituted for an instance of the inherited class. An alternative technique, delegation, requires more programming effort but avoids the substitutability issue. In C++ private inheritance can be used as form of implementation inheritance without substitutability. Whereas public inheritance represents an "is-a" relationship and delegation represents a "has-a" relationship, private (and protected) inheritance can be thought of as an "is implemented in terms of" relationship. Object Oriented Software Construction, 2nd ed. by Bertrand Meyer, the creator of the object-oriented programming language Eiffel, lists twelve different uses of inheritance, most of which involve some amount of implementation inheritance.
23 | P a g e
Limitations and alternatives When using inheritance extensively in designing a program, one should be aware of certain constraints that it imposes. For example, consider a class Person that contains a person's name, address, phone number, age, sex, and race. We can define a subclass of Person called Student that contains the person's grade point average and classes taken, and another subclass of Person called Employee that contains the person's job title, employer, and salary. In defining this inheritance hierarchy we have already defined certain restrictions, not all of which are desirable:
Constraints design
of
inheritance-based
Singleness: using single inheritance, a subclass can inherit from only one superclass. Continuing the example given above, Person can be either a Student or an Employee, but not both. Using multiple inheritance partially solves this problem, as a Student Employee class can be defined that inherits from both Student and Employee. However, it can still inherit from each superclass only once; this scheme does not support cases in which a student has two jobs or attends two institutions.
Static: The inheritance hierarchy of an object is fixed at instantiation when the object's type is selected and does not change with time. For example, the inheritance graph does not allow a Student object to become a Employee object while retaining the state of its Person 24 | P a g e
superclass. (Although similar behavior can be achieved with the decorator pattern.)
Visibility: Whenever client code has access to an object, it generally has access to the entire object's superclass data. Even if the superclass has not been declared public, the client can still cast the object to its superclass type. For example, there is no way to give a function a pointer to a Student's grade point average and transcript without also giving that function access to all of the personal data stored in the student's Person superclass.
Roles and inheritance Sometimes inheritance based design is used instead of roles. A role, say Student role of a Person describes a characteristic associated to the object that is present because the object happens to participate in some relationship with another object (say the person in student role -has enrolled- to the classes). Some objectoriented design methods do not distinguish this use of roles from more stable aspects of objects. Thus there is a tendency to use inheritance to model roles, say you would have a Student role of a Person modelled as a subclass of a Person. However, neither the inheritance hierarchy nor the types of the objects can change with time. Therefore, modelling roles as subclasses can cause the roles to be fixed on creation, say a Person cannot then easily change his role from Student to Employee when the circumstances change. From modelling point of view, such restrictions are often not desirable, because this causes artificial restrictions on future extensibility of the object system, which will make future changes harder to implement, because existing design needs to be updated. Inheritance is often better used with a generalization mindset, such that common aspects of instantiable classes are 25 | P a g e
factored to superclasses; say having a common superclass 'LegalEntity' for both Person and Company classes for all the common aspects of both. The distinction between role based design and inheritance based design can be made based on the stability of the aspect. Role based design should be used when it's conceivable that the same object participates in different roles at different times, and inheritance based design should be used when the common aspects of multiple classes (not objects!) are factored as superclasses, and do not change with time. One consequence of separation of roles and superclasses is that compile-time and run-time aspects of the object system are cleanly separated. Inheritance is then clearly a compile-time construct. Inheritance does influence the structure of many objects at runtime, but the different kinds of structure that can be used are already fixed at compile-time. To model the example of Person as an employee with this method, the modelling ensures that a Person class can only contain operations or data that are common to every Person instance regardless of where they are used. This would prevent use of a Job member in a Person class, because every person does not have a job, or at least it is not known that the Person class is only used to model Person instances that have a job. Instead, object-oriented design would consider some subset of all person objects to be in an "employee" role. The job information would be associated only to objects that have the employee role. Object-oriented design would also model the "job" as a role, since a job can be restricted in time, and therefore is not a stable basis for modelling a class. The corresponding stable concept is either "WorkPlace" or just "Work" depending on which concept is meant. Thus, from object-oriented design point of view, there would be a "Person" class and a 26 | P a g e
"WorkPlace" class, which are related by a many-to-many associatation "works-in", such that an instance of a Person is in employee role, when he works-in a job, where a job is a role of his work place in the situation when the employee works in it. Note that in this approach, all classes that are produced by this design process are part of the same domain, that is, they describe things clearly using just one terminology. This is often not true for other approaches. The difference between roles and classes is especially difficult to understand if referential transparency is assumed, because roles are types of references and classes are types of the referred-to objects.
27 | P a g e
THE BENEFITS OF INHERITANCE Some of more important benefits of inheritance are as follows:
SOFTWARE REUSABILITY When behavior is inherited from another class, the code that provides that behavior does not have to be rewritten. This may seem obvious but the implications are important. Many programmers spend much of their time rewriting code they have written many times before-for example, to search for a pattern in a string or to insert a new element in to a table. With object oriented techniques these functions can be written once and used. Other benefits of reusable code include increased reliability and the decreased maintenance cost because of sharing by all user of the code.
Code sharing: Code sharing can occur on several levels with object-oriented techniques. On one level many users or projects can use the same classes. Another form of sharing occurs when two or more classes developed by a single programmer as part of a project inherit from a single parent class. For example, a set and an array may both be considered a form of collection. When this happens, two or more types of objects will share the code that they inherit. This code needs to be written only and will contributes only once to the size of the resulting program.
28 | P a g e
Consistency of interface: Inheritance two or more classes inherit from the same super class, we are assured that the behavior they inherit will be the same in all cases. Thus, it is easier to guarantee that interfaces to similar objects are in fact similar and that the user is not presented with a confusing collection of objects that are almost same but behave and are interacted with, very differently.
Software components: Inheritance provides programmer with the ability to construct reusable software components. The goal is to permit the development of new and novel application that nevertheless require little or no actual coding. Already, several such libraries are commercially available and we can expect many more specialized systems to appear in time.
Rapid prototyping: When software system is constructed largely out of reusable components, development time can be concentrated on understanding the new and unusual portion of the system. Thus, software system can be generated more quickly and easily, leading to a style of programming known as rapid prototyping or exploratory programming. A prototype system is developed user experiment with it the first; further experimentation takes place, and so on for several iterations. Such programming is particularly useful in situations where the goals and requirement of the system are only vaguely understood when the project begins.
29 | P a g e
Polymorphism and frameworks: Software produced conventionally is generally written from the bottom up although it may be designed from the top down. That is, the lower-level routines are written and on top of these slightly higher abstractions are produced, and on top of these even more abstraction element are generated. This process is like building a wall, where every brick must be laid on top of an already laid brick. Normally, code portability deceases as one moves up the level of abstraction. That is the lower-level routines may be used in several difference projects, and perhaps even the next level of abstraction may be reused but the higher-level routines are intimately tied to a particular application. The lower-level pieces can be carried to a new system and generally makes sense standing on their own; the high level components generally make sense only when they are built on top of specific lover-level parts. Polymorphism in programming languages permits the programmer to generate high-level reusable components that can be tailored to fit different application by changes in their low-level parts.
Information hiding: A programmer who reuses software components needs only to understand nature of the component and its interface. It is not necessary for the programmer to have detailed information concerning matters such as the techniques used to implement the component. Thus, the interconnectedness between software systems is reduced. We earlier identified the interconnected nature of conventional software as being one of the principle causes of software complexity. 30 | P a g e
THE COST OF INHERITANCE The benefit of inheritance in object-oriented programming are great, almost nothing is without cost of one sort or another. For this reason we consider the cost of object oriented programming techniques and in particular cost of inheritance.
Execution speed: It is seldom possible for general-purpose software tools to be as fast as carefully handcrafted systems. Thus, inherited methods, which must deal with arbitrary subclasses, are often slower than specialized code. Yet, concern about efficiency is often misplaced. First, the difference is often small. Second, the reduction in execution speed may be balanced by an increase in the speed of software development. Finally, most programmers actually have little idea of how execution time is being used in their programs. It is far better to develop a working system, monitor it to discover where execution tine is being used and improve those sections, than to spend an inordinate amount of time worrying about efficiency early in project.
Program size: The use of any software library frequently imposes a size penalty not imposed by system constructed fir a specific project. Although this expense 31 | P a g e
may be substantial, as memory coast decrease the size of programs becomes less important. Containing development coast and producing high quality and error-free code rapidly are now more important than the size of programs.
Message passing overhead: Much has been made of the fact that message passing is by nature a more costly operation than simple procedure invocation. As with overall execution speed, however, over concern about the cost of massage passing is frequently penny-wise and pound-foolish. For one thing the increased cost is often marginal-perhaps two or three additional assembly-language instruction and a total time penalty of 10 percent. This increased cost, like other must be weighed against the many benefits of the object-oriented technique. A few languages notably C++, make number of option available to the programmer that can reduced the message- passing overhead. These include eliminating the polymorphism from message passing and expanding inline procedures. Similarly the Delphi Pascal programmer can choose dynamic methods, which use a run-time lookup mechanism, or virtual methods, which use a slightly faster technique. Dynamic methods are inheritantly slower, but require less space.
Program complexity: Object-oriented, programming is often touted as a solution to software complexity. In fact overuse of 32 | P a g e
inheritance can often simply replace one form if complexity with another. Understanding the control flow of a program that uses inheritance may require several multiple scans up and down the inheritance graph. This is known as the yo-yo problem.
Uses of Inheritance The classic examples of an inheritance hierarchy are borrowed from animal and plant taxonomies. For example, there could a class corresponding to the Pinaceae (pine) family of trees. Its subclasses could be Fir, Spruce, Pine, Hemlock, Tamarack, DouglasFir, and TrueCedar, corresponding to the various genera that make up the family. The Pine class might have SoftPine and HardPine subclasses, with WhitePine, SugarPine, and BristleconePine as subclasses of SoftPine, and PonderosaPine, JackPine, MontereyPine, and RedPine as subclasses of HardPine. There's rarely a reason to program taxonomy like this, but the analogy is a good one. Subclasses tend to specialize a superclass or adapt it to a special purpose, much as a species specializes a genus. Here are some typical uses of inheritance: •
Reusing code: If two or more classes have some things in common but also differ in some ways, the common elements can be put in an a single class definition that the other classes inherit. The common code is shared and need only be implemented once. For example, Faucet, Valve, and WaterPipe objects, defined for the program that models water use, all need a connection to a water source and they all should be 33 | P a g e
able to record the rate of flow. These commonalities can be encoded once, in a class that the Faucet, Valve, and WaterPipe classes inherit from. A Faucet can be said to be a kind of Valve, so perhaps the Faucet class would inherit most of what it is from Valve, and add very little of its own. •
Setting up a protocol: A class can declare a number of methods that its subclasses are expected to implement. The class might have empty versions of the methods, or it might implement partial versions that are to be incorporated into the subclass methods. In either case, its declarations establish a protocol that all its subclasses must follow. When different classes implement similarly named methods, a program is better able to make use of polymorphism in its design. Setting up a protocol that subclasses must implement helps enforce these naming conventions.
•
Delivering generic functionality: One implementers can define a class that contains a lot of basic, general code to solve a problem, but doesn't fill in all the details. Other implementers can then create subclasses to adapt the generic class to their specific needs. For example, the Appliance class in the program that models water use might define a generic water-using device that subclasses would turn into specific kinds of appliances. Inheritance is thus both a way to make someone else's programming task easier and a way to separate levels of implementation.
•
Making slight modifications: When inheritance is used to deliver generic functionality, set up a protocol, or reuse code, a class is devised that other classes are expected to inherit from. But you can also use inheritance to modify classes that aren't intended as superclasses. Suppose, for 34 | P a g e
example, that there's an object that would work well in your program, but you'd like to change one or two things that it does. You can make the changes in a subclass. •
Previewing possibilities: Subclasses can also be used to factor out alternatives for testing purposes. For example, if a class is to be encoded with a particular user interface, alternative interfaces can be factored into subclasses during the design phase of the project. Each alternative can then be demonstrated to potential users to see which they prefer. When the choice is made, the selected subclass can be reintegrated into its superclass.
35 | P a g e