lecture 9 intro_inheritance

Download Report

Transcript lecture 9 intro_inheritance

Inheritance
Inheritance
• Early programmers often wrote code very similar to
existing code
• Example: A human resources system might handle
different types of personnel. Much of the code for
different classifications of personnel would be identical
• This was often handled by cutting and pasting code
and then modifying
• Needed a way to capture and formalize the similarity
Inheritance
Natural, hierarchical way of organizing things.
Staff Member
Employee
Hourly
Consultant
Salaried
(superclass)
Volunteer
(subclass of Staff)
(subclass of Employee)
(subclass of Hourly)
Think in terms of “is a” relationships:
An Employee is a Staff Member, as
is a Volunteer.
An Hourly worker is a(n) Employee.
A Consultant is a(n) Hourly employee.
Classes and Subclasses
class Animal {
public String name = "";
public String noise = "";
public int numTimesPerformed
= 0;
Don’t worry
about
“private” and
“public” for
now
// constructors, accessors & modifiers go here
public void identifySelf( ) {
System.out.println(“My name is “ + name);
} // of identifySelf
public void perform( ) {
doYourThing( );
numTimesPerformed++;
} // of perform
public void doYourThing( ) {
; // ‘no-op’ method
} // of doYourThing
} // of Animal
So, animals have
a name and noise
and they can identify
themselves, perform
and do their thing.
Animal harpo = new Animal();
harpo.setName(“Harpo”);
harpo.doYourThing();
// says nothing
Subclasses
(Dog extends Animal
i.e. “A dog is an animal” or
“All dogs are animals”)
class Dog extends Animal
public Dog() {
noise = “Woof”;
} // of constructor
Animal
Dog
Cat
Human
{
Recall: The Animal
class had a no-op
method for
doYourThing()
public void doYourThing ( ) {
identifySelf();
System.out.println(“I am a dog”);
System.out.println(noise);
} // of doYourThing
Dog pickles = new Dog();
pickles.setName(“Pickles”);
} // of Dog
pickles.doYourThing();
// output:
// “My name is Pickles”
// “I am a dog”
// “Woof”
Subclasses
(Cat extends Animal
i.e. “A cat is an animal” or
“All cats are animals”)
class Cat extends Animal
public Cat() {
noise = “Miaow”;
} // of constructor
Animal
Dog
Cat
Human
{
public void doYourThing ( ) {
identifySelf();
System.out.println(“I am a cat”);
System.out.println(noise);
} // of doYourThing
Cat abby = new Cat();
abby.setName(“Abby”);
} // of Cat
abby.doYourThing();
// output:
// “My name is Abby”
// “I am a cat”
// “Miaow”
Subclasses
(Human extends Animal
i.e. “A human is an animal” or
“All humans are animals”)
Animal
Dog
Cat
Human
class Human extends Animal {
public Human() {
noise = “I think therefore I am”;
} // of constructor
public void doYourThing ( ) {
identifySelf();
System.out.println(“I am a sentient being”);
System.out.println(noise);
} // of doYourThing
Human descartes = new Human();
descartes.setName(“Rene”);
} // of Human
descartes.doYourThing();
// output:
// “My name is Rene”
// “I am a sentient being”
// “I think therefore I am”
Questions?
Inheritance & Scope
Using super & this
Inheritance and Scope
Variables (e.g. noise):
• Java first examines current method, looks for local
variable or parameter;
• Java then examines current class (e.g. Dog);
• Java then examines superclass (e.g. Animal);
• Java continues up the class hierarchy until no more
superclasses to examine.
Methods (e.g. doYourThing() or identifySelf()):
• Java first examines current class;
• Java then examines superclass;
• Java continues up inheritance hierarchy until no more
superclasses to examine.
Specifying Scope
Java allows you to override the scope rules by saying which
variable/method you’re referring to:
Keyword super:
keyword for specifying method or variable from superclass,
e.g., super.doYourThing( )
Keyword this:
keyword for specifying method or variable in current object,
e.g., this.doYourThing( )
Animal
Using super & this
(but why??)
class Dog extends Animal {
public Dog() {
super.noise = “Woof”;
} // of constructor
Dog
Human
Same (in this case) as
noise = “Woof”;
and
this.noise = “Woof”;
public void doYourThing ( ) {
super.identifySelf();
System.out.println(“I am a dog”);
System.out.println(noise);
} // of doYourThing
} // of Dog
Cat
Same (in this case) as
identifySelf();
or
this.identifySelf();
Using super and this
class Animal {
String name;
}
class Dog extends Animal {
String name; /* Just so I don't forget! */
void twoNames() {
System.out.println
("My dog name is " + name);
System.out.println
("My animal name is " + super.name);
}
}
Animal
Using super
Dog
class Dog extends Animal {
// constructor as before
public void doYourThing() {
identifySelf();
System.out.println(noise);
} // of doYourThing
Cat
Human
I.e.
this.identifySelf()
(newly defined below)
public void identifySelf() {
super.identifySelf();
System.out.println(“I am a dog”);
} // of identifySelf
} // of Dog
If omitted???
I.e. the
identifySelf()
(defined in Animal)
A geometry example
class Shape {
public String name;
Shape
public String getName ()
return (this.name);
} // getName
Rectangle
Circle
public int area () {
return (0);
} // area
} // Shape
Each extending object would override the area() method.
{
class Rectangle extends Shape {
private int length, width;
Rectangle () {
this(0, 0);
} // constructor
Rectangle (int l, int w) {
this( l, w, “rectangle”);
} // constructor
Rectangle
(int l, int w, String n) {
length = l;
width = l;
name = n;
} // constructor
public int area () {
return (length * width);
} // area
Constructor “chaining”
public String getName () {
if (length == width)
return "square";
else
return super.getName());
} // getName
public String toString () {
String s;
s = new String ("A " +
getName() +
" with length " + length
+ " and width " + width);
return (s);
}
} // toString
} // Rectangle
The Circle class implementation is left
as an exercise to the reader.
Constructors and Inheritance
Java’s rule:
• If first line of constructor is not an explicit call to a
superclass constructor, Java will implicitly put super( ) as
the first line, calling the superclass default constructor.
public Dog() {
strNoise = “Woof”;
} // of constructor
implied call to Animal() here
• An exception to this rule: chained constructor call to
this(params) will defer(ertelemek) super( ) call
• To use superclass constructors with params, call
them explicitly, e.g., super(strName)
Look Closer...
class Rectangle extends Shape {
private int length, width;
What if I want a
Shape
constructor run
here?
Rectangle () {
this(0, 0);
} // constructor
Rectangle (int l, int w) {
this( l, w, “rectangle”);
} // constructor
Rectangle (int l, int w, String n) {
length = l;
width = l;
name = n;
} // constructor
public int area () {
return (length * width);
} // area
Shape();
What if there is no
Shape()???
Error
Inheritance and Scoping
Examples:
super(xxx)
super.xxx
super.xxx( )
// calls a superclass constructor
// accesses superclass’ variable
// calls superclass’ method
this(xxx)
this.xxx
this.xxx( )
// calls a current-class constructor
// accesses current class’s variable
// calls current class’ method
Note: cannot do
super.super<something>
(can achieve this effect via casting, but rarely should;
details later...)
Chaining, superclass example
class Parent {
String name;
public Parent() {
setName("NONE"); cp(1); }
public Parent(String name) {
setName(name); cp(2); }
public void setName(String name) {
this.name = name;
cp(3); }
public void cp(int n) {
System.out.println("At checkpoint "+n+" "+name); }
public static void main(String args[]) {
Child c = new Child(); }
} // Parent
class Child extends Parent {
public Child() {
this("NONAME");
Output:
cp(4); }
At checkpoint 3 NONE
public Child(String name) {
At checkpoint 1 NONE
At checkpoint 5 NONAME
this.name = name;
At checkpoint 4 NONAME
cp(5); }
} // Child
class Parent {
String name;
public Parent() {
setName("NONE"); cp(1); }
public Parent(String name) {
setName(name); cp(2); }
public void setName(String name) {
this.name = name;
cp(3); }
public void cp(int n) {
System.out.println("At checkpoint "+n+" "+name); }
public static void main(String args[]) {
Child c = new Child("Bob"); }
} // Parent
class Child extends Parent {
public Child() {
this("NONAME");
cp(4); }
Output:
public Child(String name) {
At checkpoint 3 NONE
At checkpoint 1 NONE
this.name = name;
At checkpoint 5 Bob
cp(5); }
} // Child
Recall: Class Object
• Java provides a base class, Object
• All classes that do not have an extends clause implicitly
inherit directly from class java.lang.Object
Examples utilizing this fact:
public boolean equals (Object o);
public boolean String toString ();
• When you create your own toString( ) method for a class,
you are overriding the toString( ) provided by Object.
Object Hierarchy
Object
Animal
Dog
Cat
Human
class Object methods:
String toString()
boolean equals(Object obj)
Employee
and a few others...
Salaried
Hourly
Object
Or how about...
Animal
Dog
Cat
Human
Employee
Salaried
Hourly
Questions?
Wrapper Classes
Primitive types (e.g., int) are not classes
But sometimes, we may have need to make use of primitive types
in a context that requires that we manipulate objects, not
primitives
e.g. many collection classes are collections of Objects
Java provides a set of wrapper classes (a.k.a. type wrappers,
a.k.a. envelope classes) to support treating primitives as objects.
It does this by providing a specific class that corresponds to each
primitive data type
They are in java.lang, so the names are universally available
The names are mostly identical to primitive types, but capitalized...
Wrapper Classes
Class
Boolean
Character
Byte
Short
Integer
Long
Float
Double
corresponds to
Primitive
boolean
char
byte
short
int
long
float
double
Each one:
• allows us to manipulate primitives as objects
• contains useful conversion methods.
E.g. Integer contains
static Integer valueOf(String s)
Integer.valueOf("27")
is the object corresponding to int 27
• contains useful utility methods (e.g. for hashing)
Wrapper Classes
Using wrappers to bridge between objects and primitives:
// create and initialize an int
int i = 7;
// create an Integer object and convert the int to it
Integer intObject = new Integer( i );
// retrieve the int by unwrapping it from the object
System.out.println( intObject.intValue() );
// convert a string into an Integer object
String strS = "27";
Integer intObject
intObject = new Integer (strS);
// then to an int
int a = intObject.intValue();
// one way
int b = Integer.parseInt(strS); // second way
Questions?