6 - OOD4 Object, Type Conversion, and Polymorphism
6 - OOD4 Object, Type Conversion, and Polymorphism
Monster
+ eat()
+ reduceHealth() Hero
+ spook() + reduceHealth() Which method(s) has/have
+ useFire(w : Weapon) been overridden?
Which method(s) has/have
Orc Dragon been overloaded?
+ eat(heroes : Hero[]) + spook()
+ useFire()
QUICK REVIEW
The following code contains a compile time error. What can we
change so that an orc of health 10 with an axe can be correctly
created?
OOD4
The Object class
Type Conversion
instanceof
Intro to Polymorphism
Abstract Classes and Methods
MODIFIERS
and
INHERITANCE
ACCESS CONTROL MODIFIERS
package lectures;
package assignments.a1;
import assignments.a1.A;
public class A {
public class B extends A{
: All public classes
:
} can be extended
}
(even across
packages)
ACCESS CONTROL MODIFIERS
Outer and inner classes have access to all fields and methods of each
other. Details are out of the scope of this course.
final KEYWORD
compile-time error!
final KEYWORD
compile-time error!
Object CLASS
THE Object CLASS
Object is the only class in java without a superclass. All other classes have
one and only one direct superclass.
In the absence of any other specific superclass, every class is implicitly a
subclass of Object.
https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html
METHODS FROM Object
https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
HIERARCHY FOR OUR EXAMPLES
Object
+ hashCode(): int
+ toString(): String
+ equals(o: Object): boolean
extends (automatic)
Animal
extends
Dog
https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode--
EXAMPLE
Object
+ hashCode(): int
+ toString(): String
+ equals(o: Object): boolean
extends (automatic)
String
The class String
+ hashCode(): int overrides hashCode()
+ toString(): String
+ equals(s: Object): boolean
EXAMPLE
https://docs.oracle.com/javase/7/docs/api/java/lang/String.html
Object
+ hashCode(): int
+ toString(): String
+ equals(o: Object): boolean
toString()
The toString() method for class Object returns a string consisting of the
name of the class of which the object is an instance, the at-sign character
‘@’, and the unsigned hexadecimal representation of the hash code of the
object.
EXAMPLE
java.lang.Object@7852e922
Object
+ hashCode(): int Returns the following:
className + “@” +
+ toString(): String Integer.toHexString(hashCode())
+ equals(o: Object): boolean
extends (automatic)
toString() is overridden
String
in the class String
+ hashCode(): int
+ toString(): String
Returns the object itself
+ equals(s: Object): boolean
EXAMPLE
Object
+ hashCode(): int Returns the following:
className + “@” +
+ toString(): String Integer.toHexString(hashCode())
+ equals(o: Object): boolean
extends (automatic)
toString() is overridden
Animal
in the class Animal
- birth: Date
+ eat()
Returns… depends on your
+ toString(): String implementation!
Object
+ hashCode(): int
+ toString(): String
+ equals(o: Object): boolean
https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
equals()
Object
+ hashCode(): int
+ toString(): String
+ equals(o: Object): boolean
extends (automatic)
Animal
Animal overrides the
- birth: Date
equals() method
+ eat()
+ equals(o: Object): boolean
EXAMPLES
Object
+ hashCode(): int
+ toString(): String
+ equals(o: Object): boolean
extends (automatic)
Animal
Animal overloads the
- birth: Date
equals() method
+ eat()
+ equals(a: Animal): boolean
EXAMPLES
Object
+ hashCode(): int
+ toString(): String
+ equals(o: Object): boolean
extends (automatic)
String
String overrides the
+ hashCode(): int
equals() method
+ toString(): String
+ equals(s: Object): boolean
equals() FROM String
TYPE CONVERSION
FROM LAST TIME…
class Dog public class Test {
Person owner
public void bark() { public static void main(String[] args) {
print(“woof!”);
Dog snoopy = new Beagle();
}
: snoopy.bark();
extends }
}
class Beagle Is this
void hunt () allowed??
public void bark() {
print(“aowwwuuu”);
}
:
OBJECTS TYPE
We have seen that an object is of the type of the class from which it was
instantiated.
Note that the reverse is not necessarily true: an Animal could be a Dog,
but not necessarily. Similarly, an Object could be an Animal or a Dog,
but it isn’t necessarily.
TYPE CASTING – REFERENCE TYPES
The second line will cause a compile-time error. From the compiler point of view,
myPet is of type Animal and an Animal might not be a Dog.
However, we can tell the compiler that myPet is of the correct type, by explicitly
downcasting:
Dog myDog = (Dog) myPet;
If myPet turns out to be of the wrong type we’ll get a run-time error.
42
Animal
IMPORTANT!
extends Note that casting does NOT
change the object itself, it just
labels it differently!
Dog
Is this allowed?
Yes, it is an example of upcasting which happens automatically.
EXAMPLES
Is this allowed?
Compile-time error! The variable myDog is of type Dog, and it might not be
pointing to a Poodle. It requires explicit downcasting to compile.
EXAMPLES
Is this allowed?
The code compiles, but there will be a run-time error because myDog is not
pointing to a Poodle after all.
EXAMPLES
Is this allowed?
Compile-time error! The variable myDog is of type Dog, and there is no method
called hunt inside the Dog class.
EXAMPLES
Is this allowed?
Yes, this code will compile and run.
A LITTLE ABOUT instanceof
When can use instanceof to make sure that downcasting to a subclass will
not cause a run time error.
Note that in general we want to use instanceof as a last resort. We’ll see why
shortly.
That said, we have to use instanceof when overriding equals()
Animal
extends
Dog
public void bark() {
print(“woof!”);
}
Dog myDog = new Dog(); The compiler sees bark() in the Dog class
(myDog is of type Dog) at compile time, the
myDog.bark(); JVM invokes bark() from the Dog class at run
Dog snoopy = new Beagle(); time (myDog points to an object of type Dog).
snoopy.bark();
At compile time, the compiler uses bark() in
OUTPUT
the Dog class to validate the statement. At run
time, however, the JVM invokes bark() from
the Beagle class. (snoopy is actually
woof!
referring to a Beagle object)
aowwwuuu
THE “OO WAY”
"Anytime you find yourself writing code of the form ‘if the object
is of type T1, then do something, but if it's of type T2, then do
something else’, slap yourself”.
TRY IT!
What prints?
prints "walnut"
prints "more!!"
abstract
LET’S LOOK AT AN EXAMPLE
Suppose we created the following two classes to work with Circles and
Triangles.
Circle Triangle
- color: String - color: String
- radius: double - base: double
+ getColor(): String - height: double
+ setColor(c:String) + getColor(): String
+ getRadius():double + setColor(c:String)
+ getArea(): double +getArea(): double
LET’S LOOK AT AN EXAMPLE
Suppose we created the following two classes to work with Circles and
Triangles.
Observations:
Circle Triangle
- color: String - color: String • The two classes are
- radius: double - base: double closely related. They are
+ getColor(): String - height: double both used to represent
+ setColor(c:String) + getColor(): String geometrical shapes.
+ getRadius():double + setColor(c:String)
+ getArea(): double +getArea(): double
LET’S LOOK AT AN EXAMPLE
Suppose we created the following two classes to work with Circles and
Triangles.
Observations:
Circle Triangle
- color: String - color: String • There’s code that is
- radius: double - base: double repeated: the two classes
+ getColor(): String - height: double share fields and methods
+ setColor(c:String) + getColor(): String that are implemented in
+ getRadius():double + setColor(c:String) the same way.
+ getArea(): double +getArea(): double
LET’S LOOK AT AN EXAMPLE
Suppose we created the following two classes to work with Circles and
Triangles.
Observations:
Circle Triangle
- color: String - color: String • There’s a method that
- radius: double - base: double serves the same purpose
+ getColor(): String - height: double in both classes, but it’s
+ setColor(c:String) + getColor(): String implemented differently
+ getRadius():double + setColor(c:String) depending on the class.
+ getArea(): double +getArea(): double
LET’S LOOK AT AN EXAMPLE
Suppose we created the following two classes to work with Circles and
Triangles.
Observations:
Circle Triangle
- color: String - color: String • There are fields and
- radius: double - base: double methods that are specific
+ getColor(): String - height: double to each class.
+ setColor(c:String) + getColor(): String
+ getRadius():double + setColor(c:String)
+ getArea(): double +getArea(): double
LET’S LOOK AT AN EXAMPLE
Suppose we created the following two classes to work with Circles and
Triangles.
Observations:
Circle Triangle
- color: String - color: String • It is the perfect situation to
- radius: double - base: double create an abstract
+ getColor(): String - height: double superclass!
+ setColor(c:String) + getColor(): String
+ getRadius():double + setColor(c:String)
+ getArea(): double +getArea(): double
abstract METHODS
If you want a class to contain a particular method, but you would like the
implementation of this method to be specified by the subclasses, then you can
declare the method to be abstract.
It cannot be instantiated.
It can have final methods which will force the subclass not to
change the body of the method
abstract CLASSES – OBSERVATIONS
Circle Triangle
- radius: double - base: double
+ getRadius():double - height: double
+ getArea(): double + getArea(): double