1 / 52

Chapter 10

Chapter 10. Object-Oriented Programming Part 3: Inheritance, Polymorphism, and Interfaces. Topics. Inheritance Concepts Inheritance Design Inherited Members of a Class Subclass Constructors Adding Specialization to the Subclass Overriding Inherited Methods

giles
Télécharger la présentation

Chapter 10

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chapter 10 Object-Oriented Programming Part 3: Inheritance, Polymorphism, and Interfaces

  2. Topics • Inheritance Concepts • Inheritance Design • Inherited Members of a Class • Subclass Constructors • Adding Specialization to the Subclass • Overriding Inherited Methods • The protected Access Modifier

  3. Inheritance Concepts • A common form of reuse of classes is inheritance. • We can organize classes into hierarchies of functionality. • The class at the top of the hierarchy (superclass) defines instance variables and methods common to all classes in the hierarchy. • We derive a subclass, which inherits behavior and fields from the superclass.

  4. Inheritance • Inheritance allows a software developer to derive a new class from an existing one • The existing class is called the parent class, or superclass, or base class • The derived class is called the child class or subclass • As the name implies, the child inherits characteristics of the parent • That is, the child class inherits the methods and data defined by the parent class

  5. A Sample Vehicle Hierarchy • This hierarchy is depicted using a Unified Modeling Language (UML) diagram. • In UML diagrams, arrows point from the subclass to the superclass.

  6. Superclasses and Subclasses • A superclass can have multiple subclasses. • Subclasses can be superclasses of other subclasses. • A subclass can inherit directly from only one superclass. • All classes inherit from the Object class.

  7. Superclasses and Subclasses • A big advantage of inheritance is that we can write common code once and reuse it in subclasses. • A subclass can define new methods and instance variables, some of which may override (hide) those of a superclass.

  8. Specifying Inheritance • The syntax for defining a subclass is to use the extends keyword in the class header, as in accessModifier class SubclassName extends SuperclassName { // class definition } • The superclass name specified after the extends keyword is called the direct superclass. • As mentioned, a subclass can have many superclasses, but only one direct superclass.

  9. Business RetailBusiness ServiceBusiness KMart Macys Kinkos Class Hierarchies • A child class of one parent can be the parent of another child, forming a class hierarchy

  10. Class Hierarchies • Two children of the same parent are called siblings • Common features should be put as high in the hierarchy as is reasonable • An inherited member is passed continually down the line • Therefore, a child class inherits from all its ancestor classes • There is no single class hierarchy that is appropriate for all situations

  11. The Object Class • A class called Object is defined in the java.lang package of the Java standard class library • All classes are derived from the Object class • If a class is not explicitly defined to be the child of an existing class, it is assumed to be the child of the Object class • Therefore, the Object class is the ultimate root of all class hierarchies

  12. The Object Class • The Object class contains a few useful methods, which are inherited by all classes • For example, the toString method is defined in the Object class • Every time we define the toString method, we are actually overriding an inherited definition • The toString method in the Object class is defined to return a string that contains the name of the object’s class along with some other information

  13. Example public class ObjectExample {public static void main( String [] args ){ Object o1 = new Object(); System.out.println("This is an object " + o1); Temp t = new Temp(); System.out.println("This is a temp object " + t); } } public class Temp{ private int a; private char ch;} Output ----jGRASP exec: java ObjectExampleThis is an object java.lang.Object@10b62c9This is a temp object Temp@923e30

  14. The Object Class • The equals method of the Object class returns true if two references are aliases • We can override equals in any class to define equality in some more appropriate way • As we've seen, the String class defines the equals method to return true if two String objects contain the same characters • The designers of the String class have overridden the equals method inherited from Object in favor of a more useful version

  15. An Applet Hierarchy • When we wrote an applet,we defined a subclass. • We say that inheritance implements an "is a" relationship, in that a subclassobject "is a" superclass object as well. • Thus, RollABall "is a" JApplet (its direct superclass), Applet, Panel, Container,Component, andObject. • RollABall begins with more than 275 methods and 15 fields inheritedfrom its 6 superclasses.

  16. The Bank Account Hierarchy • The BankAccount class isthe superclass. • Instance variables: • balance (double) • MONEY (a constantDecimalFormat object) • Methods: • Default and overloaded constructors • deposit and withdraw methods • balance accessor • toString

  17. Example 10.1 public class BankAccount { public final DecimalFormat MONEY = new DecimalFormat( "$#,##0.00" ); private double balance; /** Default constructor sets balance to 0.0 */ public BankAccount( ) { balance = 0.0; } /** Overloaded constructor @param startBalance beginning balance */ public BankAccount( double startBalance ) { deposit( startBalance ); } /** Accessor for balance @return current account balance */ public double getBalance( ) { return balance; } /** toString @return the balance formatted as money */ public String toString( ) { return ( "balance is " + MONEY.format( balance ) ); }

  18. /** Deposit amount to account @param amount amount to deposit; * amount must be >= 0.0 */ public void deposit( double amount ) { if ( amount >= 0.0 ) balance += amount; else System.err.println( "Deposit amount must be positive." ); } /** withdraw amount from account * @param amount amount to withdraw; amount must be >= 0.0 * amount must be <= balance */ public void withdraw( double amount ) { if ( amount >= 0.0 && amount <= balance ) balance -= amount; else System.err.println( "Withdrawal amount must be positive " + "and cannot be greater than balance" ); } }

  19. The CheckingAccount Class • We derive the CheckingAccount subclass from BankAccount: public class CheckingAccount extends BankAccount { } • Notice that nothing is defined in the class definition, but we can still instantiate and use an instance • A subclass inherits all the public members of a superclass. Thus, the CheckingAccount class inherits • the MONEY instance variable • The getBalance, deposit, withdraw, and toString methods

  20. Example 10.3 ----jGRASP exec: java CheckingAccountClientNew checking account: balance is $0.00After depositing $350.75: balance is $350.75After withdrawing $200.25: balance is $150.50 public class CheckingAccountClient { public static void main( String [] args ) { CheckingAccount c1 = new CheckingAccount( ); System.out.println( "New checking account: " + c1 ); c1.deposit( 350.75 ); System.out.println( "\nAfter depositing $350.75: " + c1 ); c1.withdraw( 200.25 ); System.out.println( "\nAfter withdrawing $200.25: " + c1 ); } }

  21. private Members • Superclass members declared as private are part of the subclass, but not accessible by the subclass • Thus, the balance instance variable is allocated to all CheckingAccount objects, but methods of the CheckingAccount class cannot directly access balance. • To set or get the value of balance, the CheckingAccount methods must call the withdraw, deposit, or getBalance methods. • This simplifies maintenance because the BankAccount class enforces the data validation rules for balance.

  22. Subclass Constructors • Constructors are not inherited. • However, the subclass can call the constructors of the superclass to initialize inherited fields. • Implicit invocation • The default constructor of the subclass automatically calls the default constructor of the superclass • For explicit invocation, use this syntax: super( argument list ); If used, this statement must be the first statement in the subclass constructor

  23. The super Reference • A child’s constructor is responsible for calling the parent’s constructor • The first line of a child’s constructor should use the super reference to call the parent’s constructor • The super reference can also be used to reference other variables and methods defined in the parent’s class

  24. CheckingAccount Constructors public CheckingAccount( ) { // optional explicit call // to BankAccount default constructor super( ); } public CheckingAccount( double startBalance ) { // explicit call to BankAccount // overloaded constructor super( startBalance ); }

  25. Common ErrorTrap • An attempt by a subclass to directly access a private field or call a private method defined in a superclass will generate a compiler error. • To set initial values for private variables, call the appropriate constructor of the direct superclass. • For example, this statement in the overloaded CheckingAccount class constructor calls the overloaded constructor of the BankAccount class: super( startBalance );

  26. Software Engineering Tip Overloaded constructorsin a subclass should explicitly call the direct superclass constructor to initialize the fields in its superclasses.

  27. Inheritance Rules for Constructors

  28. Adding Specialization • A subclass can define new fields and methods. • Our CheckingAccount class adds • these instance variables: • monthlyFee, a double • DEFAULT_FEE, a double constant • these methods: • setMonthlyFee, the accessor • getMonthlyFee, the mutator • applyMonthlyFee, which charges the monthly fee to the account.

  29. The applyMonthlyFee Method • Because balance is private in the BankAccount class, the applyMonthlyFee method calls the withdraw method to subtract the monthly fee from the balance: public void applyMonthlyFee( ) { withdraw( monthlyFee ); }

  30. Example 10.7 public class CheckingAccount extends BankAccount { public final double DEFAULT_FEE = 5.00; private double monthlyFee; /** default constructor explicitly calls the BankAccount default constructor * set monthlyFee to default value */ public CheckingAccount( ) { super( ); // optional monthlyFee = DEFAULT_FEE; } /** overloaded constructor calls BankAccount overloaded constructor * @param startBalance starting balance * @param startMonthlyFee starting monthly fee */ public CheckingAccount( double startBalance, double startMonthlyFee ) { super( startBalance ); // call BankAccount constructor setMonthlyFee( startMonthlyFee ); }

  31. /** applyMonthlyFee method charges the monthly fee to * the account */ public void applyMonthlyFee( ) { withdraw( monthlyFee ); } /** accessor method for monthlyFee * @return monthlyFee */ public double getMonthlyFee( ) { return monthlyFee; }

  32. /** mutator method for monthlyFee * @param newMonthlyFee new value for monthlyFee */ public void setMonthlyFee( double newMonthlyFee ) { if ( monthlyFee >= 0.0 ) monthlyFee = newMonthlyFee; else System.err.println( "Monthly fee cannot be negative" ); } }

  33. Example 10.8 public static void main( String [ ] args ) { CheckingAccount c3 = new CheckingAccount( 100.00, 7.50 ); System.out.println( "New checking account: " + c3.toString( ) + "; monthly fee is “ + c3.getMonthlyFee( ) ); c3.applyMonthlyFee( ); // charge the fee to the account System.out.println( "\nAfter charging monthly fee: " + c3.toString( ) + "; monthly fee is “ + c3.getMonthlyFee( ) ); } ----jGRASP exec: java CheckingAccountClientNew checking account: balance is $100.00; monthly fee is 7.5After charging monthly fee: balance is $92.50; monthly fee is 7.5

  34. Software Engineering Tip The superclasses in a class hierarchy should contain fields and methods common to all subclasses. The subclasses should add specialized fields and methods.

  35. Overriding Inherited Methods • A subclass can override (or replace) an inherited method by providing a new version of the method. • The API of the new version must match the inherited method. • When the client calls the method, it will call the overridden version. • The overridden (original) method is invisible to the client of the subclass, but the subclass methods can still call the overridden (original) method using this syntax: super.methodName( argument list )

  36. Overriding • A method in the parent class can be invoked explicitly using the super reference • If a method is declared with the final modifier, it cannot be overridden • The concept of overriding can be applied to data and is called shadowing variables • Shadowing variables should be avoided because it tends to cause unnecessarily confusing code

  37. Shadowing Example public class CheckingAccount extends BankAccount { public final double DEFAULT_FEE = 5.00; private double monthlyFee; private double balance; // this hides the balance from BankAccount /** overloaded constructor calls BankAccount overloaded constructor * @param startBalance starting balance * @param startMonthlyFee starting monthly fee */ public CheckingAccount( double startBalance, double startMonthlyFee ) { setBalance( startBalance ); // call our mutator for initializing setMonthlyFee( startMonthlyFee ); } // whenever balance is referenced it’s the Checking Account balance // BankAccount balance is in the donut hole, but hidden, UNLESS you call a super method that access balance, and then it’s the BankAccount balance // confused?

  38. Overloading vs. Overriding • Overloading deals with multiple methods with the same name in the same class, but with different signatures • Overriding deals with two methods, one in a parent class and one in a child class, that have the same signature • Overloading lets you define a similar operation in different ways for different parameters • Overriding lets you define a similar operation in different ways for different object types

  39. The toString Method • The toString method in the CheckingAccount class overrides the toString method in the BankAccount class. • The subclass version call the superclass version to return balance. public String toString( ) { return super.toString( ) + "; monthly fee is " + MONEY.format( monthlyFee ); }

  40. Example 10.10 public class CheckingAccountClient { public static void main( String [] args ) { CheckingAccount c4 = new CheckingAccount( 100.00, 7.50 ); System.out.println( "New checking account:\n" + c4 ); } } ----jGRASP exec: java CheckingAccountClientNew checking account:balance is $100.00; monthly fee is $7.50 ----jGRASP: operation complete.

  41. Inheritance Rules for Overridden Methods

  42. Common ErrorTrap • Do not confuse overriding a method with overloading a method. • Overriding a method: • A subclass provides a new version of that method (same signature), which hides the superclass version from the client. • Overloading a method: • A class provides a version of the method, which varies in the number and/or type of parameters (different signature). A client of the class can call any of the public versions of overloaded methods.

  43. protected Members • protected members are accessible by subclasses (like public members), while still being hidden from client classes (like private members). • Also, any class in the same package as the superclass can directly access a protected field, even if that class is not a subclass. • Disadvantage: • Because more than one class can directly access a protected field, protected access compromises encapsulation and complicates maintenance of a program. • For that reason, try to use private, rather than protected, for instance variables.

  44. The protected Access Modifier • Declaring fields as private preserves encapsulation. • Subclass methods call superclass methods to set the values of the fields, and the superclass methods enforce the validation rules for the data. • But calling methods incurs processing overhead. • Declaring fields as protected allows them to be accessed directly by subclass methods. • Classes outside the hierarchy and package must use accessors and mutators for protected fields.

  45. protected fields: Tradeoffs • Advantage: • protected fields can be accessed directly by subclasses, so there is no method-invocation overhead. • Disadvantage: • Maintenance is complicated because the subclass also needs to enforce validation rules. • Recommendation: • Define protected fields only when high performance is necessary. • Avoid directly setting the values of protected fields in the subclass.

  46. Inheritance Rules

  47. Example 10.11 public class BankAccount { public final DecimalFormat MONEY = new DecimalFormat( "$#,##0.00" ); protected double balance; /** Default constructor sets balance to 0.0 */ public BankAccount( ) { balance = 0.0; } /** Overloaded constructor * @param startBalance beginning balance */ public BankAccount( double startBalance ) { deposit( startBalance ); } // rest of the class is the same

  48. Example 10.12 public class CheckingAccount extends BankAccount { public final double DEFAULT_FEE = 5.00; private double monthlyFee; /** default constructor explicitly calls the BankAccount default constructor * set monthlyFee to default value */ public CheckingAccount( ) { super( ); // call BankAccount constructor monthlyFee = DEFAULT_FEE; } /** overloaded constructor calls BankAccount overloaded constructor * @param startBalance starting balance * @param startMonthlyFee starting monthly fee */ public CheckingAccount( double startBalance, double startMonthlyFee ) { super( startBalance ); // call BankAccount constructor setMonthlyFee( startMonthlyFee ); }

  49. /** applyMonthlyFee method charges the monthly fee to the account */ public void applyMonthlyFee( ) { balance -= monthlyFee; if ( balance < 0.0 ) System.err.println( "Warning: account is overdrawn" ); } /** accessor method for monthlyFee @return monthlyFee */ public double getMonthlyFee( ) { return monthlyFee; } /** mutator method for monthlyFee * @param newMonthlyFee new value for monthlyFee */ public void setMonthlyFee( double newMonthlyFee ) { if ( monthlyFee >= 0.0 ) monthlyFee = newMonthlyFee; else System.err.println( "Monthly fee cannot be negative" ); }

  50. /* toString method * @return String containing formatted balance and monthlyFee * invokes superclass toString to format balance */ public String toString( ) { return super.toString( ) + "; monthly fee is " + MONEY.format( monthlyFee ); } }

More Related