fit1002 2006 1 fit1002 computer programming inheritance
Post on 19-Dec-2015
231 views
TRANSCRIPT
FIT1002 2006
1
FIT1002FIT1002Computer ProgrammingComputer Programming
InheritanceInheritance
FIT1002 2006
2
ObjectivesObjectivesBy the end of this lecture, students should:
• understand classes as types of objects • understand the different uses of inheritance• understand the use of concrete and abstract classes• understand the difference between single and multiple
inheritance• understand method polymorphism and its relation to late
binding• understand “static” variables and methods• understand how inheritance is used to define the basic
Java API
• be able to extract classes from a problem specification • define an effective class structure for simple
specifications• be able to extend classes supplied as a black box
Reading: Savitch, Chapter 7 (Inheritance)Savitch, p 251-267 (Static Variables and Methods)Savitch Section 8.1 (Polymorphism, late binding)
FIT1002 2006
3
Basic OO: RevisionBasic OO: Revision
• Every object has a particular type: a class
• Classes are organized with “is-a” relationships, for example “An Edible Fruit is a Fruit”.
• “is-s” relationships generate a super-class -> sub-class relationshipA sub-class is a “specialization” of the super-class.The super-class is a generalization of the sub-class.
Fruit
Edible Poisonous
FIT1002 2006
4
Basic InheritanceBasic InheritanceSub-classes inherit all properties from the super-class• instance variables• methods
For example, both edible and poisonous fruit have – a color – a name
Fruit
Edible Poisonous
color: Stringname: String
FIT1002 2006
5
Basic InheritanceBasic InheritanceSub-classes can add additional properties to the inherited ones• instance variables• methods
For example, both Edible fruit have a taste and we are interested in
their price, while Poisonous fruit cause some particular symptom
Fruit
Edible Poisonous
color: Stringname: String
taste: Stringprice: int symptom: String
FIT1002 2006
6
Basic InheritanceBasic Inheritance• Inheritance Hierarchies are not restricted to a single level.
• They can be arbitrarily deep (and are transitive)
• They cannot contain cycles. Fruit
Edible Poisonous
color: Stringname: String
taste: Stringprice: int symptom: String
Apple Orange
FIT1002 2006
7
Basic InheritanceBasic Inheritance
Fruit
color: Stringname: String
public class Fruit{
private String color;private String name;
public String getName() { return name;}
public void setName(String aName) { this.name = aName;}
public String getColor() { return color;}
public void setColor(String aColor) { this.color = aColor;}
}
FIT1002 2006
8
Basic InheritanceBasic Inheritance
Fruit
color: Stringname: String
public class Edible extends Fruit{
private String taste;private int price;
public String getTaste() { return taste;}
public void setTaste(String aTaste) { this.taste=aTaste;}
public int getPrince() { return price;}
public void setPrice(int aPrice) { this.price=aPrice;}
}
Edibletaste: Stringprice: int
FIT1002 2006
9
Basic InheritanceBasic Inheritance
Fruit
color: Stringname: String
public class Poisonous extends Fruit{
private String symptom;
public String getSymptom() { return symptom;}
public void setSymptom( String aSymptom) {
this.symptom=aSymptom;}
}
Poisonous
symptom: String
FIT1002 2006
10
Basic InheritanceBasic Inheritance
Fruitpublic class Apple extends Edible{}
public class Orange extends Edible {}Edible
taste: Stringprice: int
Apple Orange
color: Stringname: String
FIT1002 2006
11
Inheritance and PrivateInheritance and Private
Recall: “private” variables are not directly accessible as an instance variable in a sub-class.
If we want to inherit them fully, so that this is possible, we need to declare them public or drop the access modifier completely:
public class Edible extends Fruit{
String taste;int price;
…}
FIT1002 2006
12
Inheritance and PrivateInheritance and Private
A better way is to define proper set/get methods (as before).
We can then access these instance variables with the get/set methods in the subclasses, even though we can not access them directly as an instance variable:public class Fruit{
private String color;private String name;
public String getName() { return name;}
public void setName(String aName) { this.name = aName;}
…
FIT1002 2006
13
Inheritance and PrivateInheritance and Private
Example: The following access will now work:
Apple a = new Apple();
a.setTaste(“Yummy”);System.out.println(a.getTaste());
FIT1002 2006
14
Abstract Classes Abstract Classes (advanced, optional)(advanced, optional)
Not all classes are meant to have instances.Some classes are only used for a clean conceptual program structure.
Example: if we model a Green Grocer, we will not ever have a “generic fruit” on the shelves, they will always be concrete type of fruit: Thus the classes “Fruit” and “Edible” are not meant to have instances. We will only instantiate “Apple” and “Orange”.(Hopefully we won’t need “Poisonous” at all).
You can declare a class as “abstract” to declare that it cannot be instantiated directly. Nothing else in the class definition changes.
Note: an abstract class without subclasses does not make sense.
public abstract class Fruit{… }
FIT1002 2006
15
Overriding an Initialization Overriding an Initialization ValueValue
If an inherited instance variable needs to have different initialization values in different subclasses, it must be initialized in a constructor.
Note: to be on the safe side, all initializations should be performed in constructors.public class Apple extends Edible{
public Apple(int aPrice) { setColor("red"); setName("Red Delicious"); setTaste("sweet"); setPrice(aPrice);
}}
Note how the private instance variables defined in the super-classes are accessed via setMethods.
FIT1002 2006
16
Overriding an Initialization Overriding an Initialization ValueValue
If an inherited instance variable needs to have different initialization values in different subclasses, it must be initializaed in a constructor.
Note: to be on the safe side, all initializations should be performed in constructors.public class Orange extends Edible{
public Orange(int aPrice) { setColor(“orange”); setName(“Naval”); setTaste(”juicy"); setPrice(aPrice);
}}
Note how the private instance variables defined in the super-classes are accessed via setMethods.
FIT1002 2006
17
Overriding a MethodOverriding a MethodMethods are inherited in the same way from superclasses.
If a methods needs to behave differently in a subclass, it can simply be overridden by redefining it in the subclass.
Example:
Credit
balance: float
Account
deposit(float): voidwithdraw(float): booleangetBalance(): float
ChequewithdrawFee: float
creditLimit : float…..
Savings
FIT1002 2006
18
Overriding a MethodOverriding a Method
public class Account { float balance = 0.0f; … public boolean withdraw(float amount)
{
if ( balance - amount >= 0.0f )
{
balance -= amount;
return true;
}
else return false;
}
…
FIT1002 2006
19
Overriding a MethodOverriding a Methodpublic class Savings extends Account
{
private float bankFee;
… public boolean withdraw (float amount)
{
if (balance - amount - bankFee >= 0.0f)
{
balance = balance - amount - bankFee;
return true;
}
return false;
}
…
FIT1002 2006
20
Method Signature and OverridingMethod Signature and Overriding
To override a method it must have exactly the same signature:– same name– same parameters (and parameter types)
it must also have the – same return type
The only exception to this rule is that the return-type of an overriding method in a subclass may be more specific the return type given in the superclass.
FIT1002 2006
21
Method Signature and OverridingMethod Signature and Overriding
Bank Card
linkedAccount(): Account
Credit Card
linkedAccount(): Credit
Example: A general Bank Card can be linked to any account, but a Credit Card only to a Credit Account.
FIT1002 2006
22
Calling a Super Class MethodCalling a Super Class Method
You can invoke methods in the super-class from a sub-class object.
The syntax for this is “super.methodname(…parameters…)”
This is often useful to “extend” the functionality of the super-class method.
Example: withdrawing an amount x from a Savings Account is the same as withdrawing (x+bank fees) from a generic account:
FIT1002 2006
23
Calling a Super Class MethodCalling a Super Class Method
public class Savings extends Account
{
private float bankFee;
… public boolean withdraw (float amount)
{
return super.withdraw(amount+bankFee);
}
…
FIT1002 2006
24
Casting Objects Casting Objects (Advanced, optional)(Advanced, optional)
A class is like a type for object, so you would expect to be able to
use type casts. This is possible in two directions– “upcasting”: changing the type to a superclass
Savings s = new Savings();Account a = (Account) s;
“upcasting” is safe.
– “Downcasting”: changing the type to a subclass
Savings s = new Savings();Account a = (Account) s;Savings s1 = (Savings) a;
“downcasting” is dangerous: unless the object was originally created as an object of the target class it may not have all instance variables!
FIT1002 2006
25
Polymorphism and Late Binding Polymorphism and Late Binding
The final question for method calls when using inheritance is, which method implementation is actually called? Consider the following scenario.
FIT1002 2006
26
Polymorphism and Late Binding Polymorphism and Late Binding
public class Color { public String test() {
return "I'm a generic color"; }}
public class blue extends Color { public String test() {
return "I'm blue"; }}
public class red extends Color { public String test() {
return "I'm red"; }}
FIT1002 2006
27
Polymorphism and Late Binding Polymorphism and Late Binding
Which method implementation is actually called?? Consider: test(0) vs test(1)
public class Test{
public String test(int which) { Color c=null; if (which==0) c = new blue(); else c = new red(); return c.test();}
}
FIT1002 2006
28
Polymorphism and Late Binding Polymorphism and Late Binding
c is a Color object, but (depending on input is actually instantiated as a Blue or a Red object). Each of these classes implements the test method.
public class Test{
public String test(int which) { Color c=null; if (which==0) c = new blue(); else c = new red(); return c.test();}
}
FIT1002 2006
29
Polymorphism and Late Binding Polymorphism and Late Binding
The code below will print “I’m blue” for input 0 and “I’m red” for any other input. The decision which method implementation is used is based made on the type of object to which the message is sent.
public class Test{
public String test(int which) { Color c=null; if (which==0) c = new blue(); else c = new red(); return c.test();}
}
FIT1002 2006
30
Late Binding vs Early Binding Late Binding vs Early Binding
Note that there is no way how Java could have decided at compile time which method implementation to use. This has to be decided at run time. This mechanism is called “late binding” and is used to implement method polymorphism (method overriding).
Note that in contrast to this the decision between overloaded methods and operators (methods with the same name but different parameter signatures) can always be decided at compile time. This is called “early binding”.
FIT1002 2006
31
Early Binding DemonstrationEarly Binding Demonstration
Note how call of “decide()” is processed via early binding because it is overloaded. The method “test” will always return “I’m a generic color” independent of the input value.
public class OtherTest {public String test(int which) { Color c=null; if (which==0) c = new blue(); else c = new red(); return decide(c);}
public String decide(Color c) { return "I'm a generic color"; }
public String decide(blue c) { return "I'm blue"; }
public String decide(red c) { return "I'm red"; }}
FIT1002 2006
32
The “The “ÜÜberclass” Objectberclass” Object
There is a special class “Object”
Every class that you define automatically is a subclass of Object.
you don’t need to define “extends Object”.
• Object contains a toString() method
• it is inherited for every class that you defined
• you can thus immediately print a representation of any object
System.out.println(x.toString());
for debugging purposes
• Check in the Java API what this prints! Usually you will want to override this method with a more useful version.
FIT1002 2006
33
Class PropertiesClass Properties
• Some properties of objects are really not associated with the instances of the class but with the class itself.
•Example: the financial institutions duty (FID) is a government fee on all transactions of Cheque accounts. It is a percentage fee set by the government an identical for all Cheque accounts. It thus belongs to the class and not to the instances.
FIT1002 2006
34
Static VariablesStatic Variables
• Class properties in Java are declared with the keyword “static”.
• The value of a class property is stored with the class.
public class Cheque extends Account{ private float bankFee=1.2f; private static float FID=0.1f; //percentage public boolean withdraw (float amount) { float amountFID=amount*FID/100; return super.withdraw(amount+bankFee); } }
FIT1002 2006
35
Using Static VariablesUsing Static Variables
• The name of a static variable can be used as if it would be a normal instance variable.
Cheque c = new Cheque();System.out.println(c.FID);
• It can also be accessed via the class name, even if there is no instance at all
System.out.println(Cheque.FID);
FIT1002 2006
36
Using Static VariablesUsing Static Variables
Example: Keeping a counter of the number of Objects in a particular class.
public class Apple extends Edible{ public static int count = 0;
public Apple(int aPrice) { setColor("red"); setName("Red Delicious"); setTaste("sweet"); setPrice(aPrice); count ++;
}}
FIT1002 2006
37
Referencing Static Variables via Referencing Static Variables via the Classthe Class
Apple a = new Apple(11.2);Apple b = new Apple(11.2);Apple c = new Apple(11.2);
int numApples = Apple.count;
System.out.println(“You have generated “+numApples+” Apples”);
FIT1002 2006
38
Inheritance of Static VariablesInheritance of Static Variables
• Static Variables are inherited in the same way as normal instance variables.
• Keep in mind that you cannot factor out in the same way.
• Example: you want to count Apples as well as Oranges,
•you cannot move “count” into the “Fruit” class.•you need separate counts in “Apple” and “Orange”
FIT1002 2006
39
Static MethodsStatic Methods
• Methods can also be defined as “static”• Like for variables this means that they belong to the class• This is generally used for methods that do not have to be executed in the context of a particular object.
• Example: You want to write a method that totals the balances in an array of accounts. This method has to be declared in some class, but it it not associated with a particular object. Solution: define it static in Account.
• Static Methods can be invoked either using an object in the class or the class itself.
FIT1002 2006
40
Static MethodsStatic Methods
public class Account { float balance = 0.0f; public static float totalAccounts(Account[] as) { float sum = 0f; for (Account a : as) sum += a.balance; return sum; } …}
A static methd can be invoked using the class name or an instance:Account[] as = …; System.out.println(Account.totalAccounts(as));
Account a = new Account();System.out.println(a.totalAccounts(as));
in the latter case it does not matter which instance it is invoked for.
FIT1002 2006
41
““Service Classes” - LibrariesService Classes” - Libraries
• Static Methods are often used to generate libraries of functions. • The java class Math is such a library• This explains calls like
Math.sqrt(12.4);these are simply calls to static of Math
• we have used static methods in other classes before: Character.isLetter( c )
•Look up the API for these classes on the Java site!
FIT1002 2006
42
Wrapper ClassesWrapper Classes
• Methods can only be called for instances (or classes, if the moethod is static)
• Data Values (e.g. int x=931) are not instances.• You cannot define a method for a data type.
• Every data type in Java has a “Wrapper Class”
• The wrapper class contains methods and constants for the corresponding data type.
FIT1002 2006
43
Wrapper ClassesWrapper Classes
• Some valid wrapper classes are:–Integer–Float–Double–Character–Boolean
• You find their definition in the API specification.
• Examples in the class Integer– Integer.MAX_VALUE is a static constant– Integer.parseInt(String s) is a static method
it extracts an integer number from a string
FIT1002 2006
44
Main methodMain method
A special static method is the “main” method.
Any class can have a main method. It must1. be public2. be static3. have return type void4. have a single parameter of type String[]
This turns this class into an executable stand-alone program.
FIT1002 2006
45
Compiling Executables Compiling Executables (optional)(optional)
1. Compile this class in BlueJ2. Find the file “Test.class” that BlueJ has generated3. Open a terminal window, go to the same directory and
execute the program by typing: java -cp . Test
public class Test { public static void main(String[] args) { System.out.println("Hello World! "); }
FIT1002 2006
46
Compiling Executables Compiling Executables (optional)(optional)
Step 3 invokes the java runtime system (“java”), instructs it to search for classes in the current directory (“-cp .”) and invoke the main method for the class “Test”.
public class Test { public static void main(String[] args) { System.out.println("Hello World! "); }
FIT1002 2006
47
Compiling Executables Compiling Executables (optional)(optional)
The parameter (String[] args) of main contain any further words on the command line, e.g. when called as
java -cp . Test an old catargs would be an array of length 3 with the strings “an”, “old” and “cat”.The main method above prints these.
public class Test { public static void main(String[] args) { System.out.println("Hello World! "); for (String s : args) System.out.println(s); }
FIT1002 2006
48
Variable Access from Static Variable Access from Static MethodsMethods
• “A static method cannot access a non-static instance variable.”
• this is not quite correct: A static method can only access instance variables of instances that it knows explicitly.
• This should be obvious as there is no “executing” instance, there is no “this”.
FIT1002 2006
49
Extending “Black-box” ClassesExtending “Black-box” Classes
In OO programming you often just want to extend the functionality of a class that already exists.
In this case you treat the class that you extend as a “black box”.
You don’t need to know the internals of this class, just it’s API.
You then extend this class by defining a sub-class.
Example 1: To define a new type of account (“Mortgage”), we do not need to see the internals of Account, we can just sub-class it.
Example 2: Let us assume we want to extend the built-in class String so that it has a method to recognize Palindromes.
FIT1002 2006
50
Extending “Black-box” ClassesExtending “Black-box” Classes
public class Palindrome extends String {
public boolean isPalindrom() { int len = this.length(); boolean success = true; for (int i=0; i<this.length()/2; i++) success &= (this.charAt(i)==this.charAt(len-i)); return success; }
}
FIT1002 2006
51
Extending “Black-box” ClassesExtending “Black-box” Classes
public class Palindrome extends String {
public boolean isPalindrom() { int len = this.length(); boolean success = true; for (int i=0; i<this.length()/2; i++) success &= (this.charAt(i)==this.charAt(len-i)); return success; }
}
FIT1002 2006
52
Final ClassesFinal Classes
•Unfortunately this does not compile.
• This is because the class String is defined as final.
•As for variables a “final” declaration means that it cannot be modified
• For a class “final” also means that we cannot extend it (inherit from it)
• The only solution for us is to define a wrapper class for Strings
FIT1002 2006
53
Getting around the “Final” Getting around the “Final” ProblemProblem
public class Palindrome { public String text; public Palindrome(String s) { text = s; }
public boolean isPalindrom() { int len = text.length(); boolean success = true; for (int i=0; i<text.length()/2; i++) success &= (text.charAt(i)==text.charAt(len-i)); return success; }
}
FIT1002 2006
54
Constructors and Inheritance Constructors and Inheritance (advanced, optional)(advanced, optional)
Constructors are not inherited (this is obvious when you think about the fact that they must have different names and return objects of different classes).
public class Person {int age;String name;
public Person() { }
public Person( int anAge ) { if (anAge>0) this.age = anAge; else throw new Error(“Invalid Age”); }}
public class Student extends Person { int studentID;}
Student onlyhas the default constructor!
FIT1002 2006
55
Constructors and Inheritance Constructors and Inheritance (advanced, optional)(advanced, optional)
However, sub-class constructors implicitly call the parameter-less super-class constructor first
public class Person {int age;String name;
public Person() { this.name = “John Doe”; }
…}
public class Student extends Person { int studentID; public Student() { }}
new Student()
generates an object withname = “John Doe”
FIT1002 2006
56
Default Constructor & InheritanceDefault Constructor & Inheritance (advanced, optional)(advanced, optional)
Note: if you want to use a default constructor in some sub-class, its immediate super-class must have a parameter-less constructor because super() is implicitly called by the default constructor.
Therefore you should always include a parameter-less constructor if you plan to use inheritance.
FIT1002 2006
57
Using a Super-Class ConstructorUsing a Super-Class Constructor (advanced, optional)(advanced, optional)
• Sub-class constructors implicitly execute the parameter-less super-class constructor.
• You can explicitly call the other constructors of the super-class by calling “super(…parameters…)”
Pitfall: this invocation must be the first action in the constructor of the derived class!
If this is done, the parameter-less super-class constructor is not called implicitly.
• This technique is used to “extend” constructor functionality in the sub-class. In the following code we “extend” the Person constructor in the sub-class student to set all instance variables of Student:
FIT1002 2006
58
Calling a Super-Class Constructor Calling a Super-Class Constructor (advanced, optional)(advanced, optional)
public class Person { int age; String name;
public Person( int anAge, String aName ) { this.age=anAge; this.name=aName; }}
public class Student extends Person { int studentID; public Student(int anAge, String aName, int anID) { super(anAge, aName); // call to person constructor studentID = anID; }}
FIT1002 2006
59
Reminder: Multiple InheritanceReminder: Multiple Inheritance
In some situations, we might like a class to inherit from more than one other class.
For example, we may have a Boat class and a Plane class. Boat would have behaviours such as float and reverse. Plane would have behaviours such as land and take off. They would have some behaviours in common, e.g. goForward. That might be in a superclass called Vehicle.
A seaplane is a Plane, and it is also a Boat. It could inherit from both, so that it could do all of these things.
Some programming languages allow for multiple inheritance. Java does not.
This is due to the complications involved in resolving potential conflicts in multiple inheritance.