560 likes | 578 Views
Chapter 11 : Modeling with Abstraction. Objectives. After studying this chapter you should understand the following: the roles played by interfaces, abstract classes, and concrete classes; the use of protected features for the benefit of subclasses;
E N D
Objectives • After studying this chapter you should understand the following: • the roles played by interfaces, abstract classes, and concrete classes; • the use of protected features for the benefit of subclasses; • the two kinds of clients a class can have, and the additional documentation required by subclass clients regarding the implementation of superclass features; • class extension and class composition, and their proper use. • Also, you should be able to: • use abstract classes to specify class generalization; • use interfaces, abstract classes, and concrete classes to model a system. NH-Chapter 11
Review of Player interface • Interface Player implemented by several classes • classes are identical except for implementation of takeTurn. • classes contain considerable amount of duplicate code. NH-Chapter 11
Abstract classes • AbstractPlayer can contain implementations of methods common to all Player variants, • name • sticksTaken • Player subclasses inherit these methods. NH-Chapter 11
Abstract classes • An abstract class is a class that • can contain abstract methods, • cannot be instantiated. • used as basis on which to build classes by extension. NH-Chapter 11
Abstract classes • An abstract class is class: • Defines a type. • Occupies a position in the class hierarchy. • Can be the parent of other classes, abstract or not. • Has a unique parent which may or may not be abstract. • Has one or more constructors. • It can define nonabstract methods. • Has instance variables. • Concrete class: a non-abstract class. NH-Chapter 11
Abstract classes • An abstract method must be labeled abstract. publicabstractvoid takeTurn (Pile pile, int maxOnATurn); • An abstract class can inherit abstract methods • From an interface, or • From a class. NH-Chapter 11
Interfaces, abstract classes andconcrete classes • An interface • used to specify functionality required by a client. • An abstract class • provides a basis on which to build concrete servers. • A concrete class • completes server implementation specified by an interface; • furnish run-time objects; • not generally suited to serve as a basis for extension. NH-Chapter 11
Nim game, Interfaces, abstract classes andconcrete classes • In the nim game, • Interface Player defines functionality required by a player for the Game and user interface. • Abstract class AbstractPlayer contain implementation of methods common to all Player variants. • TimidPlayer, GreedyPlayer, ClerverPlayer, subclasses of AbstractPlayer, are concrete classes which complete implementation of Player interface. NH-Chapter 11
Nim game, Interfaces, abstract classes andconcrete classes • In the nim game, • Class Game is programmed using Player interface. • During execution, Game is provided with concrete instances of TimidPlayer, GreedyPlayer, or ClerverPlayer. NH-Chapter 11
Abstract class use • An abstract class factors out implementation of its concrete subclasses. • Used to exploit polymorphism. • Functionality specified in parent class can be given implementations appropriate to each concrete subclass. • Abstract class must be stable. • any change in an abstract class propagates to subclasses and their clients. • A concrete class can only extend one (abstract) class NH-Chapter 11
Interface use • Interfaces are by definition abstract. • separate an object’s implementation from its specification. • they do not fix any aspect of an implementation. • A class can implement more than one interface. • Interfaces allow a more generalized use of polymorphism; instances of relatively unrelated classes can be treated as identical for some specific purpose. NH-Chapter 11
«interface» Depictable GeometricalFigure Rectangle Interfaces, abstract classes, concrete classes public boolean isIn (Location point, Depictable figure) { Location l = figure.location(); Dimension d = figure.dimenstion(); … } NH-Chapter 11
«interface» Depictable GeometricalFigure Rectangle Interfaces, abstract classes, concrete classes public boolean isIn (Location point, Depictable figure) { Location l = figure.location(); Dimension d = figure.dimenstion(); … } • Can pass instances of WordBalloon to isIn. NH-Chapter 11
Specifying a class for extension • Two class uses: • A class can be a client to another class and use the other class as a server. • A class can also extend another class, using the other class as a basis for its implementation. NH-Chapter 11
Specifying a class for extension • Clients and subclasses have different views of a class. Needs to know only specification of SomeClass Needs to know specification and implementation of SomeClass NH-Chapter 11
abstractclass AbstractPlayer implements Player { private String name; privateint sticksTaken; //subclasses will update it. public AbstractPlayer (String name) { this.name = name; this.sticksTaken = 0; } public String name () { returnthis.name; } publicint sticksTaken () { returnthis.sticksTaken; } public String toString () { return "Player: " + name + ", took: " +sticksTaken; } } NH-Chapter 11
class TimidPlayer extends AbstractPlayer { • public TimidPlayer (String name) { • super(name); • } • publicvoid takeTurn (Pile pile, int maxOnATurn) { • pile.remove(1); • this.sticksTaken = 1; // update of AbstractPlayer • // instance variable. • } • } • Will not compile. • TimidPlayer has no access to AbstractPlayer instance variable sticksTaken. NH-Chapter 11
abstractclass AbstractPlayer implements Player { private String name; protectedint sticksTaken; … } • Now TimidPlayer has access to AbstractPlayer instance variable sticksTaken. NH-Chapter 11
Specifying a class for extension • Root of problem between AbstractPlayer and TimidPlayer: • subclass has a different, stronger relation to parent class than a client. • TimidPlayer needs to be able to tell AbstractPlayer “store this sticksTaken value.” • Subclasses needs a different “contract” with its parent than a client needs. • Use protected features to specify subclass contract. NH-Chapter 11
Planning for extension • A subclass depends on the Parent implementation. • subclass often requires access to parent’s underlying implementation structure. • correctness of a subclass can depend on the algorithms used to implement parent methods. NH-Chapter 11
Planning for extension • Class has methods that allow combination entered either digit by digit, or a single integer. • publicclass ThreeDigitLock • A combination lock with a three digit combination. • publicvoid enterDigit (int digit) • Enter a digit of the combination; lock unlocks if the three digits of the combination are entered in order. • require: 0 <= digit && digit <= 9 • publicvoid enterCombination (int combination) • Enter the three digit combination specified; lock unlocks if the three digits of the combination are entered in order. • require: 0 <= combination && combination <= 999 NH-Chapter 11
Planning for extension • Build lock that keeps track of total number of digits entered. publicclass InstrumentedLock extends ThreeDigitLock { privateint digitCount; … publicvoid enterDigit (int digit) { digitCount = digitCount + 1; super.enterDigit(digit); } publicvoid enterCombination (int combination) { digitCount = digitCount + 3; super.enterCombination(combination); } … } NH-Chapter 11
Planning for extension • Problem: ThreeDigitLock’s enterCombination method is implementing by invoking enterDigit three times: • publicclass ThreeDigitLock { • … • publicvoid enterCombination (int combination) { • int remainder = combination; • int position = 100; • while (position > 0) { • ¹ enterDigit(remainder / position); • remainder = remainder % position; • position = position / 10; • } • } • … • } NH-Chapter 11
Planning for extension • Due to implementation of enterCombination in ThreeDigitClass class, InstrumentedLock should not increment digitCount. • InstrumentedLock subclass design depends on ThreeDigitClass’s algorithm used in enterCombination. • ThreeDigitLock must document method implementation. NH-Chapter 11
Planning for extension • publicvoid enterCombination (int combination) • Enter the three digit combination specified; lock unlocks if the • Three digits of the combination are entered in order. • This implementation invokes enterDigit three times, • once for each digit in the specified combination. • require:0 <= combination && combination <= 999 NH-Chapter 11
Planning for extension • General rules to design classes for extension: • Document any internal use of class’s overridable methods. • Constructors should not invoke class’s overridable methods . NH-Chapter 11
Planning for extension • Prevent class extension by declaring a class final. publicfinalclass ThreeDigitLock { … • Prevent method overriding by declaring method final. publicfinalvoid enterCombination (int combination){… NH-Chapter 11
Composition revisited • Uses of composition • a component is an intrinsic part of an object. • a class formed as an aggregation of components, where components exist independently of aggregation. • to “wrap” an existing class in order to alter its interface. NH-Chapter 11
Class extension and class composition NH-Chapter 11
«interface» has-a Player PlayStrategy TimidStrategy TimidStrategy GreedyStrategy GreedyStrategy CleverStrategy CleverStrategy «interface» Player AbstractPlayer Class extension OR class composition? NH-Chapter 11
Class extension v.s. class composition NH-Chapter 11
Class extension v.s. class composition • Two advantages of class extension • code reuse • polymorphism. NH-Chapter 11
Class extension v.s. class composition • Disadvantages of class extension • Changes to a superclass specification propagate to clients andsubclasses NH-Chapter 11
Class extension v.s. class composition • Other disadvantages of class extension • classes are not always designed and documented for extension. • a subclass is committed to maintain specifications inherited from its superclass. NH-Chapter 11
Class extension v.s. class composition • Advantages of composition • Existing classes can be used in composed classes. • Can change object’s behavior dynamically. • Supports stronger encapsulation than does inheritance. • Can change specification of composed class without changing core. • Composed class depends only on specification of core class, not on its implementation. • Implementation changes in core class do not propagate to composed class. NH-Chapter 11
Class extension v.s. class composition • InstrumentedLock does not depend on implementation of ThreeDigitLock. NH-Chapter 11
Class extension v.s. class composition • Composition can add functionality to an object. NH-Chapter 11
Class extension v.s. class composition • Conclusion: • reuse through composition produces more flexible code. • must not ignore advantages of polymorphism via inheritance. • lose polymorphism with composition. • But can gain it back by composing with interfaces and defining core classes that implement them. NH-Chapter 11
Extension, composition, and modifying functionality • Poor use of extension : to model roles objects play. • result in awkward constructions in which detailed knowledge of an object’s possible roles is spread throughout the application. NH-Chapter 11
Extension, composition, and modifying functionality • Poor use of extension : model roles objects may play. • Example: model card player, and card dealer. • Solution: • specify Player • use extension to specify Dealer. • Problem: change Player role to Dealer role (and vice-versa). • Solution (Ackward) : Make any Player an instance of Dealer. Switch roles via Dealer state condition. NH-Chapter 11
Extension, composition, and modifying functionality • Good use of composition : to model roles objects may play. • Example: model card player, and card dealer. • Solution: • specify Player • specify Dealer having a Player instance as a component. • Problem: change Player role to Dealer role (and vice-versa). • Solution: Dealer instance can be assigned object Player at run-time. NH-Chapter 11
AbstractPlayer TimidPlayer CleverPlayer WageringTimidPlayer BlufferTimidPlayer Extension, composition, and modifying functionality • Poor use of extension: provide alternate implementations of functionality. • can lead to a combinatorial explosion in class hierarchy NH-Chapter 11
has implementation SomeClass Implementation void service() void service() implementation.service(); Extension1 Extension2 Implementation1 Implementation2 Extension, composition, and modifying functionality • Good use of composition: provide alternate implementations of functionality. • Bridge pattern: Separate abstraction hierarchy from implementation hierarchy. NH-Chapter 11
Extension and object state • “Kind” of thing object models and object “state” are related. • Model several categories of students: junior division students, undergraduates, graduate students, etc. publicclass Student { … // Student classifications: publicstaticfinalint JUNIOR_DIVISION = 0; publicstaticfinalint UNDERGRADUATE = 1; publicstaticfinalint GRADUATE = 2; privateint classification; … publicint classification () { … } … publicvoid setClassification (int class) { … } … } NH-Chapter 11
Extension and object state • Some of the functionality of a Student is state dependent. • Code depending on student’s classification via case analysis. int classification = someStudent.classification(); if (classification == Student.JUNIOR_DIVISION) { handle JUNIOR_DIVISION case } elseif (classification == Student.UNDERGRADUATE) { handle UNDERGRADUATE case } elseif (classification == Student.GRADUATE) … NH-Chapter 11
Extension and object state • Problem with structure: • method containing this code is dependent on student classifications. • such structured conditionals scattered throughout implementation. • maintenance complication: adding new classification requires modifications in a number of places,. • long conditionals handling many cases are hard to understand and difficult to modify or extend. • Such structures are generally undesirable in an object-oriented system. NH-Chapter 11
Extension and object state • Better structure: subclass Student to model different classifications. • Classification-dependent behavior handled by providing different implementations in subclass methods. • New classification is handled by defining a new subclass. • Clients depend on polymorphism for appropriate behavior. NH-Chapter 11
State as an object • Difficulty with subclassing classification. • Class of an object is fixed when the object is created. • Subclassing (static) does not support (dynamic) type transfer from one subclass to another. NH-Chapter 11
State as an object • Better structuring of Student with classification that changes dynamically: • Define interface isolating state-dependent behavior. • Equip object with a state-defining component that implements interface. • Different behaviors achieved by providing different subclasses for component. • State-dependent requests forwarded to state component. NH-Chapter 11