Chapter 8 Extending classes with inheritance ©The McGraw-Hill Companies, 2006 Extending classes with inheritance • inheritance is the sharing of attributes and methods among classes on a hierarchical basis; • we take a class, and then define other classes based on the first one; • the new classes inherit all the attributes and methods of the first one, but also have attributes and methods of their own. • say an Employee class has: – two attributes, number and name; – a user-defined constructor; – some basic get- and set- methods for the attributes. • we wish a PartTimeEmployee class to: – – – – inherit these attributes and methods have an additional attribute, hourlyPay; have some methods to access this attribute; have one additional method, calculateWeeklyPay. ©The McGraw-Hill Companies, 2006 UML uses a triangle to denote inheritance: ©The McGraw-Hill Companies, 2006 Implementing inheritance in Java - the PartTimeEmployee class The header • using the keyword extends means that the PartTimeEmployee class (the subclass) inherits all the attributes and methods of the Employee class (the superclass); • therefore although we haven't coded them, any object of the PartTimeEmployee class will have, for example, an attribute called name and a method called getNumber.; • a PartTimeEmployee is now a kind of Employee. ©The McGraw-Hill Companies, 2006 Potential problem • the attributes have been declared as private in the superclass; • thus, although they are now part of our PartTimeEmployee class, none of the PartTimeEmployee class methods can directly access them; • the subclass has only the same access rights as any other class. Possible solutions Solution 1 • we could declare the original attributes as public; • but this would take away the whole point of encapsulation. Solution 2 • we could use the special keyword protected instead of private; • anything declared as protected is accessible to the methods of any subclasses; Solution 3 • leave the attributes as private, but plan carefully in advance which get and set methods you are going to provide. ©The McGraw-Hill Companies, 2006 The attribute • this declares an attribute, hourlyPay, which is unique to the subclass; • remember that the attributes of the superclass, Employee, will be inherited, so in fact any PartTimeEmployee object will have three attributes. The constructor • we want to be able to assign values to the number and name at the time that the object is created; • the constructor will need to receive parameters that will be assigned to the number and name attributes. ©The McGraw-Hill Companies, 2006 Question • how are we going to do this when the number and name attributes have been declared as private in the superclass ? Answer • we can call the constructor of the superclass by using the keyword super: • the line that calls super has to be the first one. ©The McGraw-Hill Companies, 2006 the remaining methods of PartTimeEmployee are new methods specific to the subclass: ©The McGraw-Hill Companies, 2006 Extending the Oblong class • the original Oblong class had the capability of reporting on the perimeter and area of the oblong; • the extended class will have the capability of sending back a string representation of itself composed of a number of symbols such as asterisks - for example: ***** ***** ***** • we can think of the instruction to start a new line as just another character; • for convenience we can call <newline>; • our string could be written like this. *****<newline>*****<newline>***** • in Java we are able to represent this <newline> character with a special character that looks like this: '\n' ©The McGraw-Hill Companies, 2006 ©The McGraw-Hill Companies, 2006 Analysis of The ExtendedOblong class The constructor ©The McGraw-Hill Companies, 2006 The draw method • this introduces the new concept of type casting: ©The McGraw-Hill Companies, 2006 Type casting • type casting means forcing an item to change from one type to another; • the draw method is going to create a string of one or more rows of stars or crosses or whatever symbol is chosen; • the dimensions of the oblong are defined as doubles; • the draw method needs to be dealing with whole numbers of rows and columns; • so we must convert the length and height of the oblong from doubles to ints; • there will be some loss of precision here, but that won't matter in this particular case. ©The McGraw-Hill Companies, 2006 type casting is achieved by placing the new type name in brackets before the item you wish to change: ©The McGraw-Hill Companies, 2006 Method overriding • you have seen that one way of achieving polymorphism is by method overloading; • this involves methods of the same class having the same name, but being distinguished by their parameter lists; • another way of achieving polymorphism is by method overriding. • consider a class called Customer, and a subclass of this called GoldCustomer. ©The McGraw-Hill Companies, 2006 ©The McGraw-Hill Companies, 2006 • notice that the method dispatchGoods appears in both the superclass and the subclass, and that its interface is identical in both classes. • the Customer class has three attributes: – the first represents the customer's name; – the second, totalMoneyPaid represents the total amount of money that a customer has paid so far; – the third, totalGoodsRecieved, represents the value of the goods that have so far been dispatched to the customer; • normally, goods would not be dispatched to a customer unless the customer had already paid for them; • for goods of a particular value to be dispatched, the difference between totalMoneyPaid and totalGoodsReceived must therefore be at least as much as the value of the goods. ©The McGraw-Hill Companies, 2006 • Certain customers - known as "gold" customers - have extra privileges and are given a credit limit; • in the case of such a customer, goods can be dispatched as long as the credit limit is not exceeded; • the behaviour of the dispatchGoods method is therefore going to be different in the case of the superclass and that of the subclass; • we cans define the method in the superclass, and then define a different version in the subclass; • in other words we can override the method in the subclass, thus achieving polymorphism. Note • in the case of method overloading, the different methods were distinguished by the parameter lists; • in the case of method overriding, they are distinguished by the object with which they are associated. ©The McGraw-Hill Companies, 2006 • We have made the attributes protected so that they will be visible in the subclass; • The calculateBalance method returns the current balance of the customer's account - that is the difference between the total amount of money paid by the customer, and the total value of the goods that the customer has received so far. • The recordPayment method simply records the fact that a customer has made a payment by adding the amount of the payment to the total amount that the customer has paid. • The dispatchGoods method first checks that the customer has enough money in his or her account to pay for the goods that are to be dispatched; if this is the case the value of the goods being dispatched is added to the total value of the goods received so far, and a value of true is returned; if the customer does not have enough funds to pay for the goods (that is, the balance is less than the value of the goods) a value of false is returned; the return value could be used by the calling method to determine whether or not the goods should actually be sent out to the customer. ©The McGraw-Hill Companies, 2006 - Notes on the GoldCustomer class The dispatchGoods method • we have a method in the subclass with exactly the same name, the same parameter list, and the same return value (in other words the same interface) as a method in the superclass; • however, in the original method in the superclass (Customer), we checked whether the customer had sufficient funds with the following condition: • in the subclass (GoldCustomer) the condition has to take into account the fact that the customer is allowed a negative balance up to the limit of his or her credit: ©The McGraw-Hill Companies, 2006 • consider the following lines in a program: • in the first call to dispatchGoods, the version of the method as defined in Customer will be called, because it is associated with a Customer object, firstCustomer; • in the second call to dispatchGoods, the version of the method as defined in GoldCustomer will be called, because it is associated with a GoldCustomer object, secondCustomer. ©The McGraw-Hill Companies, 2006 Abstract classes ©The McGraw-Hill Companies, 2006 Note • we have included a new method in the Employee class, called getStatus - which also appears in both subclasses. • the two subclasses contain the attributes and methods appropriate to the class; • in fact any employee will always be either a full-time employee or a part-time employee; • there is never going to be a situation in which an individual is just an "employee"; • so users of a program that included all these classes would never find themselves creating objects of the Employee class; • it would therefore be a good idea to prevent people from doing this; • we do so by to declaring the class as abstract; • once a class has been declared in this way it means that you are not allowed to create objects of that class; • the Employee simply acts a basis on which to build other classes. ©The McGraw-Hill Companies, 2006 Why use abstract methods? • say a method of some class expects to receive as a parameter an object the Employee class; • inside this method there is some code that calls a particular method of Employee – for example a method called getStatus; • inheritance means that an object of any subclass of Employee is a kind of Employee; • it can therefore be passed as a parameter into a method that expects an Employee object; • however, this subclass must have a getStatus method for it to be able to be passed as a parameter into a method that calls getStatus; • by declaring the abstract method getStatus in the superclass we can insist that every subclass must have a getStatus method; • we can tell anyone who is going to use a derivative of Employee to go ahead and call a getStatus method because it will definitely be there. ©The McGraw-Hill Companies, 2006 The final modifier • you know that final can be used to modify a variable and turn it into a constant; • in the case of a class it is placed before the class declaration, like this: • this means that the class cannot be subclassed. • in the case of a method it is used like this: • this means that the method cannot be overridden. ©The McGraw-Hill Companies, 2006 The Object class • in Java, every single class that is created is derived from what we might call a special "super superclass"; • this super superclass is called Object; • so every object in Java is in fact a kind of Object. • this allows us to create very generic methods - methods that can receive any kind of object; • it also allows us to create generic arrays - arrays of Objects. ©The McGraw-Hill Companies, 2006 Wrapper classes and autoboxing How could you use an array of Objects to store a simple type such as an int or a char - or to pass such a type to a method that expects an Object? •for every primitive type, Java provides a corresponding class; •the name of the class is similar to the basic type, but begins with a capital letter. •for example: – Integer; – Character; – Float; – Double. •they are called wrapper classes because they "wrap" a class around the basic type. •an object of the Integer class, for example, holds an integer value. ©The McGraw-Hill Companies, 2006 Example • imagine we had created and array of objects as follows: • one way of storing an integer value such as 37 in this array would be: • the constructor of the Integer class accepts a primitive value and creates the corresponding Integer object; • here we have created an Integer object from the primitive value 37, and this is now stored in the array. • Java 5.0, however, allows us to make use of a technique known as autoboxing; • this involves the automatic conversion of a primitive type such as an int to an object of the appropriate wrapper class; • this allows us to do the following: ©The McGraw-Hill Companies, 2006 • one way to retrieve this value from this array and assign it to an int would be: • we type cast from Object back to Integer; • the Integer class provides a getValue method to retrieve the primitive value form the object. • Java 5.0 also allows us to make use of a technique called unboxing that converts from the wrapper class back to the primitive type; • so the above could be written as: ©The McGraw-Hill Companies, 2006 A mixed list • program 8.5 creates an array that is going to hold a mixture of different objects at the same time - some fulltime employees and some part-time employees. • so, we are going to have an array that at some particular time could look like this: ©The McGraw-Hill Companies, 2006 Test run from program 8.5 Enter the employee number: 1 Enter the employee's name: Jones <F>ull-time or <P>art-time? f Enter the annual salary: 30000 Enter the employee number: 2 Enter the employee's name: Agdeboye <F>ull-time or <P>art-time? f Enter the annual salary: 35000 Enter the employee number: 3 Enter the employee's name: Sharma <F>ull-time or <P>art-time? p Enter the hourly pay: 15 Employee number: 1 Employee name: Jones Status: Full-Time Employee number: 2 Employee name: Agdeboye Status: Full-Time Employee number: 3 Employee name: Sharma Status: Part-Time ©The McGraw-Hill Companies, 2006
© Copyright 2025 Paperzz