550 likes | 556 Views
COMP201 Java Programming. Topic 4: Inheritance Readings: Chapter 5. Outline. Introduction Basics Deriving a subclass Using subclasses More advanced issues Inheritance of static methods and fields Abstract classes Final classes
E N D
COMP201 Java Programming Topic 4: Inheritance Readings: Chapter 5
Outline • Introduction • Basics • Deriving a subclass • Using subclasses • More advanced issues • Inheritance of static methods and fields • Abstract classes • Final classes • The object class and generic programming (ArrayList class)
Introduction to Inheritance Technique for deriving a new class from an existing class. Existing class called superclass, base class, or parent class. New class is called subclass, derived class, or child class.
Introduction to Inheritance • Subclass and superclass are closely related • Subclass share fields and methods of superclass • Subclass can have more fields and methods • Implementations of a method in superclass and subclass can be different • An object of subclass is automatically an object of superclass, but not vice versa • The set of subclass objects is a subset of the set of superclass objects. (E.g. The set of Managers is a subset of the set of Employees.) This explains the term subclass and superclass.
Introduction to Inheritance Why inherit? • Employee class: name, salary, hireDay; getName, raiseSalary(), getHireDay(). • Manageris-aEmployee, has all above, and • Has a bonus • getsalary() computed differently • Instead of defining Manager class from scratch, one can derive it from the Employee class. Work saved.
Checking method A method B1 Account method A superclass Saving method A method B2 checking method B1 saving method B2 subclass Introduction to Inheritance Why inherit? Inheritance allows one to factor out common functionality by moving it to a superclass, results in better program.
Basics/Deriving a Subclass • General scheme for deriving a subclass: class subClassName extends superClassName { constructors refined methods additional methods additional fields } Indicate the differences between subclass and superclass
Basics/Deriving a Class • Fields for subclass • Fields of superclass + additional fields • private fields of superclass cannot be directly accessed when defining or refining methods for subclass. (After all, the subclass is another class!) • protected fields can (more on this later). • Subclass must have its own constructors • Constructors are not inherited (Superclass does not know the additional fields of its subclass and hence it does not know how to create objects of its subclass.)
Basics/Deriving a Class • Methods for subclass • publicor protected-access methods of superclass that are not refined. • Refined methods. • Additional methods • No multiple inheritance: a subclass can only extend ONE superclass
Example: Superclass class Employee { public Employee(String n, double s, int year, int month, int day) {…} public void getSalary() {…} public void raiseSalary(double byPercent) {…} private String name; private double Salary; private Date hireDay; }
Example: Subclass • Extending Employee class to get Manager class class Manager extends Employee { public Manager(…) {…} // constructor public void getSalary(…) {…} // refined method // additional methods public void setBonus(double b){…} // additional field private double bonus; }
Basics/Constructor for Subclass • Every constructor of a subclass must invoke a constructor of its superclass to initialize fields of the superclass. (Subclass cannot access them directly) • Use keyword super to invoke constructor of the superclass . public Manager(String n, double s, int year, int month, int day) { super(n, s, year, month, day); bonus = 0; } Must be the first line
Basics/Constructor for Subclass • If subclass constructor does not call a superclass constructor explicitly, then superclass uses its default (no-argument) constructor. class FirstFrame extends JFrame { public FirstFrame() { setTitle("FirstFrame"); setSize(300, 200); } } super() implicitly called here
Basics/Constructor for Subclass • Constructors are not inherited. • Let’s say Employee has two constructors public Employee(String n, double s, int year, int month, int day) public Employee(String n, double s) • Manager has one constructor public Manager(String n, double s, int year, int month, int day) new Manager(“George”, 20000, 2001, 7, 20 ); //ok new Manager(“Jin”, 25); //not ok
Basics/ Overriding Method • Salary computation for managers are different from employees. So, we need to modify the getSalary, or provide a new method that overridesgetSalary public double getSalary() {double baseSalary = super.getSalary(); returnbasesalary + bonus; } • Cannot replace the last line with salary += bonus; Because salary is private to Employee. Call method of superclass
Basics/Overriding Method • An overriding method must have the same signature (name and parameter list) as the original method. Otherwise, it is simply a new method: • Original Method in Employee: public double getSalary(){…} public void raiseSalary(double byPercent){…} • New rather than overriding methods in Manager: public void raiseSalary(int byPercent){…} public void raiseWage(double byPercent){…}
Basics/ Overriding Method • An overriding method must have the same return type as the original method: • The following method definition in Manager would lead to compiler error: public int getSalary(){…} • private methods cannot be overridden.
Basics/ Additional Methods public void setBonus(double b) { bonus = b; }
Basics/Methods for Subclass Inherited getName, getHirDay, raiseSalary Refined getSalary. Additional Manager, setBonus.
Note about this • Refer to another constructor in the same class class Employee { public Employee(String n, double s, int year, int month, int day){…} public Employee(String n) // another constructor { this(n, 0, 0,0,0); // salary default at 0 }
Note about this • Refers to the current object public Employee(String n, double s, int year, int month, int day) { this.name = n; this.salary = s; GregorianCalendar calendar = newGregorianCalendar(year, month - 1, day); // GregorianCalendar uses 0 for January this.hireDay = calendar.getTime(); }
Note about super A special keyword that directs the compiler to invoke the superclass method • Refers to constructor of superclass public manager(String n, double s, int year, int month, int day) { super(n, s, year, month, day);} • Invokes a superclass method public double getSalary() { double baseSalary = super.getSalary(); return baseSalary + bonus; } It does not refer to an object. There isn’t another object to refer to!
Note about Protected Access • A subclass can access protectedfields and methods of a superclass • Example: If the hireDay field of Employee is made protected, then methods of Manager can access it directly. • However, methods of Manager can only access the hireDay field of Managerobjects,not of other Employee objects. • Protected fields are rarely used. Protected methods are more common, e.g. cloneof theObjectclass (to be discussed later)
Employee Secretary Manager Programmer Executive Basics/Inheritance Hierarchies • Can have multiple layers of inheritance: class Executive extends Manager { ….} • Inheritance hierarchy: inheritance relationships among a collection of classes
Basics/Using Subclasses • Subclass and superclass are closely related. • How are objects of subclass and objects of superclass related? • Class compatibility:An object of subclass is automatically an object of superclass, but not vice versa. • An Manager object is an Employee object. • Polymorphism: Let harry be a Manager object. Consider the method call harry.getSalary(); Because harry can be viewed as an object of both Manager and Employee, the following questions arise: • Does the method called belong to Manager or Employee? • How does Java virtual machine decide this? (Dynamic binding)
Basics/Class Compatibility • Object of a subclass can be used in place of an object of a superclass Manager harry = new Manager(…); Employee staff = harry; Employee staff1 = new Manager(…); harry automatically cast into an Employee, widening casting. • Why staff.getSalary() is ok? • Employee has method getSalary. No compiling error. • Correct method found at run time via dynamic binding
Basics/Class Compatibility The opposite is not true Employee harry = new Employee(…); Manager staff = harry; // compiler error Manager staff1 = new Employee(…); // compiler error Use instanceofoperator to avoid class incompatibility. Manager daniel = new Manager(…); Employee staff = daniel; if (staff instanceof Manager) { Manager someone = (Manager) staff; ……. } Narrowing cast
Basics/Narrowing Casting • Narrowing cast is necessary when and only when • Object of subclass was cast into object of a superclass, and want to get back the original class type. Manager carl = new Manager(…); Employee staff = carl; // This will produce a compiler error, since Employee // doesn’t has setbonus method staff.setbonus(5000); //cast is required to get back the original class type Manager b = (Manager) staff; b.setbonus(5000);
Basics/Polymorphism • Method call: case 1 Employee harry = new Employee(…); harry.getSalary(); // calls method of Employee • Method call: case 2 Manager carl = new Manager(…); carl.getSalary(); // calls method of Manager • Method call: case 3 Manager carl = new Manager(…); Employee staff = carl; staff.getSalary(); • Calls method of Employee or Manager? • Answer: method of Manager.
Basics/Polymorphism The fact that an object variable (such as the variable staff ) can refer to multiple actual types is called polymorphism. Automatically selecting the appropriate method at runtime is called dynamic binding.
publicclass Shapes { publicstatic Shape randShape() { switch((int)(Math.random() * 3)) { default: case 0: return new Circle(); case 1: return new Square(); case 2: return new Triangle(); } } publicstatic void main(String[] args) { Shape[] s = new Shape[9]; // Fill up the array with shapes: for (int i = 0; i < s.length; i++) s[i] = randShape(); // Make polymorphic method calls: for (int i = 0; i < s.length; i++) s[i].draw(); } }
class Shape { void draw() {} void erase() {} } class Circle extends Shape { void draw() { System.out.println("Circle.draw()"); } void erase() { System.out.println("Circle.erase()"); } } class Square extends Shape { void draw() { System.out.println("Square.draw()"); } void erase() { System.out.println("Square.erase()"); } } class Triangle extends Shape { void draw() { System.out.println("Triangle.draw()"); } void erase() { System.out.println("Triangle.erase()"); } }
Basic/Dynamic Binding • Dynamic binding: Method calls are not generated at compile time. Instead of generated at run time. • Search for method that is appropriate for the actual type of the object. • If not found, move to the superclass, and so on. • Example: Manager carl = new Manager(…); Employee staff = carl; //Try Manager. Not found. Move to Employee. staff.getHireDay(); Staff.getSalary(); //Try Manager. Found. • Implication: method in subclass hides (overrides) method in superclass This is a simplified description!
Basics/Using Subclasses/Example public class ManagerTest { public static void main(String[] args) { Manager boss = new Manager("Carl Cracker", 80000, 1987, 12, 15); boss.setBonus(5000); Employee[] staff = new Employee[3]; staff[0] = boss; staff[1] = new Employee("Harry Hacker", 50000, 1989, 10, 1); staff[2] = new Employee("Tommy Tester", 40000, 1990, 3, 15); // print out information about all Employee objects for (int i = 0; i < staff.length; i++) { Employee e = staff[i]; System.out.println("name=" + e.getName() + ",salary=" + e.getSalary()); } }}//ManagerTest.java
More Advanced Issues Inheritance of Static Methods and Fields Static instance fields are inherited but not duplicated in subclass. class Employee //StaticInherit.java { public Employee (…) { … numCreated++; } public static int getNumCreated() { return numCreated; } … private static int numCreated=0; } Manager b = new Manager(…); // numCreated = 1 Employee e = new Employee(…); // numCreated = 2 Employee.getNumCreated(); // 2 Manager.getNumCreated(); // 2
More Advanced Issues Inheritance of Static Methods and Fields To count number of Managers separately, declare a new static variable in Manager class class Manager extends Employee { public Manager (…) { … numManager++; } public static int getNumCreated() { return numManager; } … private static int numManager=0; } //StaticInherit1.java
More Advanced Issues Prevent Inheritance Using final • Final class • Declared with keyword final • Cannot be sub-classed. • All methods are final. final class Executive extends Manager { …. }
More Advanced Issues Prevent Inheritance Using final • Final method: • Declared with keywordfinal • Cannot be overridden in subclass Class Employee { … public final String getName() {…} }
More Advanced Issues Prevent Inheritance Using final • Reasons to usefinal methods (and final classes): • Efficiency: • Compiler put final method in line: e.getName() replaced by e.name. • No function call. • No dynamic binding. • Safety: • Other programmers who extend your class cannot redefine a final method.
More Advanced Issues Abstract Classes • An abstract method is a method that • Cannot be specified in the current class (C++: pure virtual function). • Must be implemented in non-abstract subclasses. • An abstract class is a class that may contain one or more abstract methods
Person Student Employee More Advanced Issues Abstract Classes • Consider two classes: Employee and Student • Common methods: • getName • getDescription: returns • Employee: “an employee with salary $50,000” • Student: “a student majoring in Computer Science” • To write better code, introduce a superclass Person with those two methods
More Advanced Issues Abstract Classes abstract class Person { public Person(String n) { name = n;} public abstract String getDescription(); public String getName() { return name;} private String name; } • The getDescription method is made abstract because the Person class knows nothing about the person except for the name. We don’t know how to implement the method in the Person class although we know it must be there.
More Advanced Issues Abstract Classes • Cannot create objects of an abstract class: New Person(“Micky Mouse”) // illegal • An abstract class must be extended before use. (The opposite of final class). class Student extends Person { public Student(String n, String m) { super(n); major = m;} public StringgetDescription() { return "a student majoring in " + major; } private String major; }
More Advanced Issues Abstract Classes class Employee extends Person { … public String getDescription() { NumberFormat formatter = NumberFormat.getCurrencyInstance(); return "an employee with a salary of " + formatter.format(salary); } … private double salary; }
More Advanced Issues Abstract Classes Person[] people = new Person[2]; people[0]= new Employee("Harry Hacker", 50000, 1989,10,1); people[1]= new Student("Maria Morris", "computer science"); for (int i = 0; i < people.length; i++) { Person p = people[i]; System.out.println(p.getName() + ", " + p.getDescription()); } //PersonTest.java • This would not compile if we don’t have getDescription in Person.
A Diversionjava.text.NumberFormat and Factory Methods • Three formats for double x = 10,000.0/3.0 • 3,333.333 (Number) • $3,333.33 (Currency) • 333,333% (percentage) • Use java.text.NumberFormat to print the output in the appropriate format
A Diversionjava.text.NumberFormat and Factory Methods NumberFormat formatter = NumberFormat.getNumberInstance(); System.out.println(formmatter.format(x));//3,333.333 NumberFormat formatter = NumberFormat.getCurrencyInstance(); System.out.println(formmatter.format(x)); //$3,333.33 NumberFormat formatter = NumberFormat.getPercentInstance(); System.out.println(formmatter.format(x));//333,333%
A Diversionjava.text.NumberFormat and Factory Methods • Consider the following (static) methods of NumberFormat Class • NumberFormat.getNumberInstance() • NumberFormat.getCurrencyInstance() • NumberFormat.getPercentInstance() • Their purpose is to generate objects of class NumberFormat, hence called factory methods. • Why not constructors? • We want three objects of the same types but work differently. Factory methods offer a good solution. • Factory methods can return objects of subclasses and hence more general than constructors.
Object IS-A Array Number String . . . . Integer Double The Object class and Generic Programming • The Object class (java.lang.Object) is the mother of all classes • Everything eventually is related to Object • Never write class Employee extends Object {…} because Object is taken for granted if no explicitly superclass: class Employee {…}
The Object class and Generic Programming • Has a small set of methods • boolean equals(Object other); • x.equals(y); for any reference values x and y, this method returns true if and only if x and y refer to the same object (x==y has the value true). • Must be overridden for other equality test, e.g. name, or id E.g. Overridden in String • StringtoString(); • Returns a string representation of the object • System.out.println(x) calls x.toString() • So does “”+x • Override it if you want better format. • Useful for debugging support • Other methods to be discussed later.