Inheritance and Casting
Download
Report
Transcript Inheritance and Casting
Inheritance
v2.2
225 City Avenue, Suite 106
Bala Cynwyd, PA 19004
610.206.0101, phone
610.206.0102, fax
www.learnquest.com
Learning Objectives
Overview of Inheritance
The super keyword
Inheritance Models
The “Is-A” Relationship
The extends keyword
Abstract Classes
Extension, Overriding
and Overloading
Casting
2
Chapter Overview
Now that we’ve gotten a better
sense of Java programming we’ll
return to the idea of inheritance
and look at it more closely
After reviewing the basic ideas,
we’ll introduce three important
new ones:
- overriding
- overloading
- the super keyword
We’ll also look at re-factoring,
take another look at abstract
classes and introduce casting
3
Inheritance Overview
An inheritance relationship is one of the fundamental mechanisms
for code reuse in object-oriented programming
Inheritance allows classes to be derived from an existing class
The class which inherits is called: the subclass, the derived
class or the child class
The class which is inherited from is called: the superclass, the
base class or the parent class
A subclass inherits variables and methods from its superclass and
all of its ancestors unless those elements are scoped as private or
package
4
Inheritance in Java
The general form of subclass:
class subclassname extends superclassname
{
variables declaration ;
methods declaration ;
}
The keyword extends signifies that the
properties of the superclassname are extended
to the subclassname
6
java.lang.Object
If a class does NOT include the extends keyword, it
is assumed to extend java.lang.Object
All Java classes ultimately inherit from Object
This means that all classes in Java share the
methods found in Object. Take a moment to
examine some of these methods in the online
documentation.
7
Inheritance in Java (con’t)
Multilevel Inheritance
Multilevel Inheritance allows several levels of superclass
In Java a class can only extend from one other class
A
B
– A is superclass of B
– B is superclass of C
– This works in Java: B and
C each have only one
superclass.
C
9
Inheritance in Java (con’t)
Hierarchical Inheritance
Hierarchical Inheritance has
one superclass and many
subclasses
A
– A is superclass
– B and C are subclasses of A
B
C
– This works in Java.
10
An Example Superclass
public class Car
{
private int speed;
// The default Constructor
public class Car() {}
// A constructor that sets speed
public Car(int s) {this.setSpeed(s);}
public int getSpeed() { return speed;}
public void setSpeed(int s){speed = s;}
}
11
An Example Subclass
public class StationWagon extends Car
{
private int cargo_weight;
public void setCargoWeight(int w) {
cargo_weight = w;
}
public int getCargoWeight() {
return cargo_weight;
}
}
12
Implications of extends
The subclass becomes a specialization of the
existing class through one or more of the following
three mechanisms:
The subclass adds new data members and/or
methods
The subclass “overloads” existing methods
The subclass “overrides” existing data members
and methods
Overloading and overriding are covered in the next
set of slides
13
Overloading Existing Methods
An overloaded method has the same name as
another method in the same class (or in a parent
class) but has a different parameter list
An overloaded method provides specialized
functionality by accepting a different parameter list
14
Overloading Example
In our SportsCar class we want the option of setting
the speed more precisely via a double
public class SportsCar extends Car
{
double preciseSpeed;
//overloading setSpeed(int) from Car
public void setSpeed(double s) {
preciseSpeed = s;
}
}
15
Overriding Existing Methods
An overridden method is a method, in a subclass,
that has exactly the same signature as a method
in a parent class
You can overload methods in the same class
but you can only override methods in a
subclass
16
Overriding Example
Our StationWagons are not allowed to go more than
50 miles per hour. We enforce this via an overridden
setSpeed method
public class StationWagon extends Car
{
//overriding setSpeed(int) from Car
public void setSpeed(int s) {
if(s >50)
s = 50;
speed = s; //what’s wrong here????
}
}
17
The super Keyword
When you override a
method, the code in
the parent’s class
method is no longer
available to the subclass
If you want to access
the parent’s code you
can use the super
keyword. To call
setSpeed in Car for
StationWagon you
would do this:
public class StationWagon
extends Car
{
public void setSpeed(int s) {
if(s > 50)
s = 50;
super.setSpeed(s);
}
}
18
Overriding Existing Data
It is also possible to override data members
This is not considered good design practice. You are
subverting rather than specializing the original
superclass
Inheritance should not be used to wipe out features
that you don’t want in a subclass
19
Constructors and Inheritance
A constructor may include the super() statement to
call the constructor of the superclass from which it
inherits
In a constructor, super can only be the first statement
in the constructor’s code block (comments excepted!).
This is okay…
public StationWagon() {
…this is not.
public StationWagon() {
System.out.println(“Okay”);
System.out.println(“Okay”);
super();
}
super();
}
20
Constructors and Inheritance (con’t)
To call a specific constructor in the superclass, the
super() statement should be provided with
parameters that match that constructor:
public class StationWagon extends Car
{
//All StationWagons start of going 40.
public StationWagon() {
super(40);
System.out.println(“Okay”);
}
}
21
The protected Modifier
If an attribute or method is declared as protected
then its visible to all subclasses
This visibility also extends across package
boundaries!
22
The “Is A” Relationship
Inheritance should typically be used to model an “is –
a” relationship between Superclass and Subclass
StationWagon is a Car
Penguin is a Bird
Factory is a Workplace
While “is a” is a matter for philosophical debate on
occasion it is a good metric for building a well
engineered inheritance relationship
23
When “Is-A” Breaks Down
public class Bird {
public void fly (int altitude)
{ /* code here */}
}
public class Penguin extends Bird
{
public void fly (int altitude) { /* ??? */}
}
A penguin clearly “is-a” bird but not all penguins can fly!
24
What NOT To Do – Version 1
One (bad) solution is to let Penguins fly() but create a fly method
that doesn’t do anything:
public class Penguin extends Bird
{
public void fly (int altitude) {}
}
If someone tries to make a penguin “fly” they are probably
expecting it to work – somehow. But nothing will happen:
myPenguin.fly (1000); // nothing happens
mySwallow.fly (1000); // fly to 1000 feet
25
What NOT To Do – Version 2
Another (bad) solution is to give Penguins a fly() method
which actually means something else. Perhaps fly() for a
penguin should be swim!
public class Penguin extends Bird {
public void fly (int alt){ /* swim code here */ }
}
This makes the purpose of the code difficult to understand – objects
may respond to methods in unexpected, inappropriate ways!
myPenguin.fly (1000); // swim 1000 feet in depth
mySwallow.fly (1000); // fly 1000 feet in height
26
Solution : Refactor the Relationship
Bird
fly()
FlyingBird
Swallow
FlightlessBird
Penguin
Refactor the hierarchy into Bird, FlightlessBird
and FlyingBird!
Then build your specific class abstractions!
27
Abstract Classes Revisited
To close out this chapter, we’ll revisit abstract classes
Although we’ve already covered this, abstract classes
bear a rather subtle relationship to our next topic:
Interfaces
A review now will help you better understand the
material in the next chapter.
For our review we will consider items (Books, VHS
tapes and DVDs) being lent from a library
28
Abstract Classes
An Abstract class is a class that may not be
instantiated
An abstract class may include:
Attributes
Abstract Methods – these methods have no code
blocks
Methods – these methods have code blocks
29
Abstract Class Example
public abstract class Car {
protected int speed;
protected boolean engineState;
/* Other attributes omitted to save space */
// We’ve decided to not provide a
// default way of setting speed.
public abstract void setSpeed();
public boolean getEngineState () {
return engineState;
}
/* Other methods omitted to save space. */
}
30
Concrete Class Example
public class SportsCar extends Car
{
int horse_power;
public int setSpeed(int new_speed) {
if(new_speed > horse_power*1.7)
new_speed = horse_power*1.7;
this.speed = new_speed;
}
/* Other methods omitted to save space. */
}
31
Abstract Class Syntax
public abstract class Car { … }
A class that is abstract must be declared using the
keyword abstract
This indicates that it may NOT be instantiated
Car x = new Car();
This will cause a compilation error
32
Abstract Method Syntax
public abstract void setSpeed(int new_speed);
The keyword abstract in a method signature indicates that the
method must be implemented by an extending (or “concrete”)
class
If a class does not provide an implementation for an abstract
method it inherits it must also be declared abstract – or the
code will not compile
Note: it is possible for an abstract class to have no
abstract methods!
33
Building a “Concrete” Class
A Concrete class extends an abstract class and provides an
implementation for all inherited abstract methods:
public class SportsCar extends Car {
int horse_power;
public int setSpeed(int new_speed) {
if(new_speed > horse_power*1.7)
new_speed = horse_power*1.7;
this.speed = new_speed;
}
public int getHorsePower(){ return horse_power;}
/* Other methods omitted to save space. */
}
34
Key Design Implications
An abstract class can provide general functionality
and data fundamental to all concrete subclasses
through implemented methods; however such
functionality may not make sense on its own
Abstract methods collectively specify a list of
methods that all concrete subclasses must
implement
35
Using Abstract References
It is possible to assign concrete objects to abstract references
Car mySportsCar = new SportsCar();
However, in this example, mySportsCar only has access to
the attributes and methods defined in Car. Methods defined in
SportsCar are NOT available to it:
boolean x = mySportsCar.getEngineState();
// no problem this is a method in Car
int hp = mySportsCar.getHorsePower();
/* this will not compile – Car doesn’t have a
definition for getHorsePower() – it’s a SportsCar
method! */
36
Using Abstract References (con’t)
This enables us to write what is often called
polymorphic code, the ability for unrelated classes to
respond to common messages - we’ll address this is
detail later
BUT this technique allows us to group objects that
are similar as long as we work only with the attributes
and methods they have in common
See the example on the next slide
37
Using Abstract References (con’t)
The method below will accept ANY class that extends Car.
This includes SportsCar, Cargo, SUV and StationWagon
All classes that extend Car are required to have a
setSpeed() method. So we know that the line
aCar.setSpeed(55) will work
public void travelAtSpeedLimit (Car aCar) {
aCar.setSpeed(55);
}
38
Casting: An Introduction
In Java, classes are arranged in a strict hierarchy. Every
class – except class Object- has one superclass and
can have any number of subclasses
Our SUV class for example inherits from Cargo, which in
turn inherits from Car which inherits from Object
Object
Car
Cargo
SUV
Java guarantees that:
SUV will have all the attributes and methods of
Cargo, Car and Object
Cargo will have all the attributes and methods of Car
and Object but not SUV
Car will have all the attributes and methods of
Object but not Cargo or SUV
39
Upcasting
Because of these guarantees Java allows us to
regard a class as any one of the classes from which it
inherits
So we can choose to regard an SUV as a Cargo
object, a Car object or even just a plain old Object
object
When we do this we lose access to the attributes and
methods in the subclass
Regarding a class as one of its superclasses is called
“upcasting”
40
Upcasting Syntax
We’ve already seen one way to upcast:
Car myCar = new SportsCar();
But what if we already have a SportsCar and want
to create a Car reference to it? Well, we’d do this:
SportsCar mySportsCar = new SportsCar();
Car myCar = (Car)mySportsCar;
As we continue through this class we’ll see a variety
of ways in which this is useful
41
Downcasting
Downcasting lets us take a class which has been
upcast to a more general class and switch back to
regarding it as a more specific class
For example:
// Create a SportsCar and regard it as a Car
Car myCar = new SportsCar();
// Now create a new reference to regard myCar
// as a SportsCar
SportsCar mySportsCar = (SportsCar)myCar;
42
Issues with Casting
In many cases Java can check at compile time to
ensure that you’ve got the correct type
But this is not always so. As we will see in the
chapter on Collections, Java will not always be able
to determine that you’ve specified the right types
when it compiles your code
So, if you make a mistake you may encounter a run
time error
43
Any Questions?
After discussing this
chapter with your
instructor please
complete the exercises in
Lab 5
These exercises will
focus on abstract classes
and casting
44