Section 9.2. Inheritance

   

9.2 Inheritance

We have discussed the benefits of inheritance in object-oriented programming in previous chapters. One of the best ways to be successful as a Java programmer is to understand your problem space and appropriately assign the members a place within a hierarchy that achieves a balance between encapsulation and access.

Note

Java handles inheritance somewhat differently than other object-oriented languages you may be familiar with. C++ and Lisp both allow multiple inheritance, meaning that a class can have more than one immediate parent. In Java, as in Smalltalk, this is not allowed. A Java class may have only one immediate parent class. Some of the same utility that multiple inheritance allows, however, can be achieved using interfaces, which we discuss in the next section.


Inheritance allows you to create a class that defines characteristic fields and behaviors that are common to more than one type of related thing. Once you have defined the general class, other classes can define more specific fields and methods that are appropriate only to them.

The typical example to illustrate inheritance conceptually is the animal kingdom. All animals share certain characteristics. Different kinds of animals share more specific kinds of behavior. For instance, you could define a method for animals called move() . Then every subclass of animal that you define would inherit the ability to move. A Fish subclass could define it more specifically for swimming, and a Cat subclass could walk and pounce. You could have a Human subclass that defined data fields for language, eye color, and so on, and all humans would inherit the ability to access a language, and they would all have an eye color .

Note

A subclass is a more specific version of a superclass. A specific kind of animal is a Cat, and a Cheetah is a specific kind of Cat. Cheetahs can do everything Cats can do, and they have all the properties of Cats. Cats can do everything animals can do, and they have all of the properties of animals.


Another common way to think of inheritance is with shapes . You can define a general shape, and you can then make Triangle , Circle , and Square classes to make objects of.

The way that you use inheritance in Java is by writing the general class (the superclass) and then writing the specific class (the subclass). You specify that the subclass should inherit from some other class by using the keyword extends , like this:

 class ASubClass extends ASuperClass {...} 

In our WWWBooks example, we had employees and managers. Managers are employees , but they are a specific kind of employee. Why redefine FirstName , LastName, SSN, and so on for both of the classes when they will always both need them? It is probably better to define such shared items in the Employee class, and do this:

 class Manager extends Employee {} 

It is just at this moment when we encounter the real art of Java programming. The second we type the above line of code, we realize that these aren't the only two players in this problem space. There are also Customers . And Customers have a FirstName and a LastName, but they do not have an SSN (that we can know about). Maybe the thing to do is to define a Person class. Let Person define names , phone numbers , and so forth. Then do this instead:

 class Person {     // define firstname, lastname ... } class Customer extends Person {     // get all the Person stuff and allow Customer to have      // Orders ...} class Employee extends Person {     // get all the Person stuff and all Employee to have a     // salary and hireDate ...} class Manager extends Employee {     // get everything from Employee and also define     // a final field: QUARTERLY_BONUS = salary * 1.5; ...} 

There is no hard and fast answer to this question. Maybe it is a good idea. Maybe it doesn't do enough for you to make it worth the extra effort of keeping track of it. It depends on what your problem space is and what the goals of your program are.

You may specify only one superclass for any subclass. This is illegal:

 class Manager extends Person, Employee {...} // WRONG! 

This differs from C++, which does allow this (it's called multiple inheritance).

A subclass does not inherit the private members (fields and methods) of a superclass. Variables declared private are accessible only by other members of their own class. This may sound like a serious restriction, but it makes perfect sense: It forces you to design for encapsulation. All you have to do to access a private field in a superclass is use an accessor method to retrieve that data.

Now let's take a look at an example.

9.2.1 MakeEmployeeAndManager.java

 public class MakeEmployeeAndManager {     public static void main(String[] args) {             // make employees         Employee emp1 = new Employee("Rod");         Employee emp2 = new Employee("Tod");             // set salaries for employees         emp1.setSalary(18000.00);         emp2.setSalary(25000.00);         System.out.println(emp1.name + "'s salary: $" + emp1.getSalary());         System.out.println(emp2.name + "'s salary: $" + emp2.getSalary());             // make Manager. Pass name up to the superclass (Employee)             // for construction         Manager mgr1 = new Manager("Ned");             // set salary. Use Employee method to do this--             // the setSalary method is NOT defined in Manager class         mgr1.setSalary(125000);             // setBonus is defined in Manager class.             // you can't do this with Employee objects         mgr1.setBonus(250000.50);         System.out.println(mgr1.name + "'s combined salary and bonus: " +             (mgr1.getSalary() + mgr1.getBonus()) );     } } 

9.2.2 Employee.java

 /*   * Employee.java  *  */ /**  *  * @author  eben  * @version  */ public class Employee {     protected String name = "";     protected double salary = 0.0;     /** constructor */     public Employee(String name) {         this.name = name;     }     public void setSalary(double salary) {         this.salary = salary;     }     public double getSalary() {         return salary;     } } 

9.2.3 Manager.java

 public class Manager extends Employee {     private double bonus;     /** constructor for Manager just passes         along required info to superclass */     public Manager(String name) {         super(name);     }     void setBonus(double bonus) {         this.bonus = bonus;     }     public double getBonus() {         return bonus;     } } 

The output of running the MakeManagerAndEmployee program is as follows :

 Rod's salary: 000.0  Tod's salary: 000.0 Ned's combined salary and bonus: 5000.5 

You have used the properties and methods defined in the superclass ( Employee ) in the subclass Manager . Managers are Employees, but they are a special kind of Employee. So Managers get everything that Employees get ”a name and a salary ”but they also get a bonus. There is no reason to replicate the definition of methods for setting and getting names in Manager, and there is no reason to allow all Employees to set and get bonuses when only a specific kind of Employee (the Manager) will need to use those methods. Thus, inheritance keeps your code clean, simple, easy to manage, and encapsulated.

Notice that Managers might have bonuses, but they might not. So the Manager constructor ”the special method that creates Manager objects ”simply calls super() ; that is, the constructor of its superclass Employee . If the above listings are hard to follow, it's because we've not covered some of these topics yet. That is the purpose of the following several sections of this chapter.

9.2.4 Constructors and super

If the subclass constructor does not explicitly call the superclass constructor with super , then the superclass's no-arg constructor is implicitly called prior to any code being executed in the subclass's constructor. You must make the call to super the first line in the subclass constructor. Notice what this means: When a subclass is compiled, the compiler will throw an error if a call to super is made and the superclass does not have a no-arg constructor. That's because a default no-arg constructor is automatically added by the compiler to any class that doesn't define any constructors. This is only the case, however, when no constructors are explicitly defined.

In the following example, we will build on the knowledge of working with exceptions that we gained in the last chapter. Recall that an Exception is an object. It can be subclassed, and we can define data in that subclass and pass it to more subclasses. We can also pass a message back up the tree for the superclass to handle.

Here we will create a subclass of Exception , and then we'll create related subclasses of that to handle the particular kind of exceptions that we want to throw.

9.2.5 AgeExceptionTest.java

[View full width]
 
[View full width]
package javaforcf.chp9; /** * <p>Title: AgeException</p> * <p>Description: Demos creating your own exceptions and * using inheritance</p> * @version 1.0 */ class AgeException extends Exception { int age; AgeException(String msg) { super(msg); } // no-arg constructor AgeException() { super(); } } class TooYoungException extends AgeException { int ageLimit; TooYoungException(int age, int ageLimit) { super("You are too young!"); this.age = age; } } class TooOldException extends AgeException { int ageLimit; TooOldException(int age, int ageLimit) { super("You are too old!"); this.age = age; } } public class AgeExceptionTest { static void trySomething(int age, String action) throws TooYoungException, graphics/ccc.gif TooOldException { System.out.println("You are trying to " + action + " at age " + age + "..."); if (age < 16) throw new TooYoungException(age, 16); else if (age > 65) throw new TooOldException(age, 65); } public static void main(String[] args) { int age = 14; String action = "drive"; String conclusion = "We can be in Vegas by midnight!"; try { trySomething(age, action); System.out.println("I love to " + action + "."); } catch (TooYoungException tye) { System.out.println(tye.getMessage()); } catch (TooOldException toe) { System.out.println(toe.getMessage()); } finally { System.out.println(conclusion); } } }

   
Top


Java for ColdFusion Developers
Java for ColdFusion Developers
ISBN: 0130461806
EAN: 2147483647
Year: 2005
Pages: 206
Authors: Eben Hewitt

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net