Software Engineering for Students A Programming Approach

Software Engineering for Students A Programming Approach Software Engineering for Students A Programming Approach

web.firat.edu.tr
from web.firat.edu.tr More from this publisher
21.08.2013 Views

15.5 Polymorphism 211 which is clumsy and long-winded. This uses the keyword instanceof to ask if an object is a member of a named class. If there are a large number of graphical objects, there are a correspondingly large number of if statements. Avoiding this complexity demonstrates how powerful and concise polymorphism is. As we have seen in this small example, polymorphism often makes a segment of program smaller and neater through the elimination of a series of if statements. But this achievement is much more significant than it may seem. It means that such statements as: sprite.display(paper); know nothing about the possible variety of objects that may be used as the value of sprite. So information hiding (already present in large measure in an OOP) is extended. We can check this by assessing how much we would need to change this program to accommodate some new type of graphical object (some additional subclass of Sprite), say a laser. The answer is that we would not need to modify it at all – we could simply add the new object. This means that the program is enormously flexible. Thus polymorphism enhances modularity, reusability and maintainability. Polymorphism helps construct programs that are: ■ concise (shorter than they might otherwise be) ■ modular (unrelated parts are kept separate) ■ easy to change and adapt (for example, introducing new objects). In general, the approach to exploiting polymorphism within a particular program is as follows: 1. identify any similarities (common methods and variables) between any objects or classes in the program 2. design a superclass that embodies the common features of the classes 3. design the subclasses that describe the distinctive features of each of the classes, whilst inheriting the common features from the superclass 4. identify any place in the program where the same operation must be applied to any of the similar objects. It may be tempting to use if statements at this location. Instead, this is the place to use polymorphism. 5. make sure that the superclass contains an abstract method corresponding to the method that is to be used polymorphically. The code fragment shown above, with an array list and a for loop, is an example of a commonly occurring situation in software, where the entire contents of a collection are processed. It is so common that some languages provide a foreach control structure. In Java, the above for loop can be rewritten more concisely as: for (Object item : game) { ((Sprite) item).display(paper); } >

212 Chapter 15 ■ Object-oriented programming > Each time that the for statement repeats, it obtains the next element from the array list game. 15.6 ● Single versus multiple inheritance As we have seen, Java supports single inheritance – a class can inherit from only one immediate superclass. Seen as a class diagram, the relationships between classes appear as a tree (a computer science tree, with the root at the top). Smalltalk, Ada, C# and Visual Basic.Net also provide single inheritance. However, the widely used language C++ provides multiple inheritance, as does Eiffel. In such a language, a class can inherit from not just one but several superclasses. In life we are not just a person, we also belong to other categories, such as brothers, daughters, soccer lovers, carnivores. So a class representing a person is a subclass of all these superclasses, inheriting variables and methods from them all. There is no doubt that multiple inheritance is more complicated – both to provide in the language and to use. C++ was widely seen as an overcomplicated language and subsequent languages, such as Java and C#, have seen simplifications in many areas, including abandoning multiple inheritance in favor of single. In some languages, including Java and C#, one role of multiple inheritance has been replaced by the interface facility described in Chapter 16 on programming in the large. 15.7 ● Generics The strong typing philosophy of programming languages like Java and Ada can have a detrimental effect on programming efficiency. For example, suppose we defined a stack of strings class with the normal stack operations of push and pop, as posed in the self-test question above. If we subsequently needed another stack type but one in which the elements were Booleans rather than strings then clearly the specification and implementation would be identical apart from the different stack element types. In some languages, our only recourse would be to duplicate the stack code, but with minor differences. A more powerful stack abstraction is required which allows the stack element type to be parameterized. We will use the Java cyberspace invaders game discussed above to see how generics can be used. An array list named game contains objects representing various items (alien, bomb, laser) at various positions within a panel. To display all the shapes, we execute a loop: for (int s = 0, s < game.size(); s++) { sprite sprite = (Sprite) game.get(s); sprite.display(paper); } Notice that the objects retrieved from the array list need to be casted into Sprite objects using a casting operator, (Sprite) in this case. This is because an array list >

212 Chapter 15 ■ Object-oriented programming<br />

><br />

Each time that the <strong>for</strong> statement repeats, it obtains the next element from the array<br />

list game.<br />

15.6 ● Single versus multiple inheritance<br />

As we have seen, Java supports single inheritance – a class can inherit from only one<br />

immediate superclass. Seen as a class diagram, the relationships between classes appear<br />

as a tree (a computer science tree, with the root at the top). Smalltalk, Ada, C# and<br />

Visual Basic.Net also provide single inheritance.<br />

However, the widely used language C++ provides multiple inheritance, as does<br />

Eiffel. In such a language, a class can inherit from not just one but several superclasses.<br />

In life we are not just a person, we also belong to other categories, such as brothers,<br />

daughters, soccer lovers, carnivores. So a class representing a person is a subclass of all<br />

these superclasses, inheriting variables and methods from them all.<br />

There is no doubt that multiple inheritance is more complicated – both to provide<br />

in the language and to use. C++ was widely seen as an overcomplicated language and<br />

subsequent languages, such as Java and C#, have seen simplifications in many areas,<br />

including abandoning multiple inheritance in favor of single. In some languages,<br />

including Java and C#, one role of multiple inheritance has been replaced by the interface<br />

facility described in Chapter 16 on programming in the large.<br />

15.7 ● Generics<br />

The strong typing philosophy of programming languages like Java and Ada can have a<br />

detrimental effect on programming efficiency. For example, suppose we defined a stack of<br />

strings class with the normal stack operations of push and pop, as posed in the self-test<br />

question above. If we subsequently needed another stack type but one in which the elements<br />

were Booleans rather than strings then clearly the specification and implementation<br />

would be identical apart from the different stack element types. In some languages, our only<br />

recourse would be to duplicate the stack code, but with minor differences. A more powerful<br />

stack abstraction is required which allows the stack element type to be parameterized.<br />

We will use the Java cyberspace invaders game discussed above to see how generics<br />

can be used. An array list named game contains objects representing various items<br />

(alien, bomb, laser) at various positions within a panel. To display all the shapes, we execute<br />

a loop:<br />

<strong>for</strong> (int s = 0, s < game.size(); s++) {<br />

sprite sprite = (Sprite) game.get(s);<br />

sprite.display(paper);<br />

}<br />

Notice that the objects retrieved from the array list need to be casted into Sprite<br />

objects using a casting operator, (Sprite) in this case. This is because an array list<br />

>

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!