Title: Todays Material
1Todays Material
- Abstraction and Inheritance
- Base class or superclass
- Derived class or subclass
2Inheritance Motivation
- Consider our Square, Rectangle, Triangle and
Circle classes. What do you observe? - They are all shapes and share common properties
Square
Triangle
Rectangle
Circle
-x int -y int -height int
-x int -y int -width int
-x int -y int -width int -height int
-x int -y int -radius int
getX()int getY()int setX(int) setY(int) get
Width()int setWidth(int) draw(char)
getX()int getY()int setX(int) setY(int) get
Height()int setHeight(int) draw(char)
getX()int getY()int setX(int) setY(int) get
Radius()int setRadius(int) draw(char)
getX()int getY()int setX(int) setY(int) get
Width()int getHeight()int setWidth(int) setHe
ight(int) draw(char)
3Inheritance Motivation
- Square, Rectangle, Triangle and Circle classes
are all shapes and share common properties - If we implement them separately as shown in their
UML-diagrams, certain functions, e.g., getX,
getY, setX, and setY will be implemented by all
shapes. This results in a lot of code
duplication! - Question Can we design a class that represents
the common state behavior for all these
classes, and have these classes borrow (inherit)
these common properties from that class? Clearly
this would avoid code duplication.
4Abstraction Inheritance
- Determining the common properties of a set of
classes and collecting them into a superclass
or base class is called abstraction - Having these classes borrow (inherit) the common
properties from the superclass is called
inheritance. The inheriting class is called a
derived class or subclass
5Benefits of Inheritance
- Avoids code duplication
- By collecting common behavior (methods) in one
place (superclass), you would have to implement
the code once only in the superclass - Allows code reuse and easier code maintenance
- Subclasses simply borrow (inherit) common
behavior from the superclass. If common code
needs to change, you have to change it in one
place only in the superclass - Allows polymorphism
- Allows the design of flexible, easily extensible
code
6Inheritance How
Shape
x int y int
getX()int getY()int setX(int) setY(int) pri
ntInfo()
Square
Rectangle
Triangle
Circle
-width int
-width int -height int
-height int
-radius int
getWidth()int setWidth(int) draw(char)
getRadius()int setRadius(int) draw(char)
getHeight()int setHeight(int) draw(char)
getWidth()int getHeight()int setWidth(int) s
etHeight(int) draw(char)
7Inheritance
- Use inheritance if subclass IS-A superclass
- Square IS-A Shape? (sounds OK)
- Rectangle IS-A Shape? (sounds OK)
- Triangle IS-A Shape? (sounds OK)
- Circle IS-A Shape? (sounds OK)
- If IS-A relationship is not satisfied, then your
inheritance hierarchy must be wrong - Computer IS-A Shape? (does not sound OK!)
8Another Example
- Assume you have an application that needs to
model Animals such as Dog, Cat, Sheep, Horse - How would you model this application?
- Clearly, all objects have the common property of
being an Animal - So, you would have a superclass called Animal,
and have all animals derive from OR extend this
class
9Animal Inheritance Hierarchy
Animal
abstract
makeNoise() eat()
specific
Cat
Horse
Dog
Sheep
Terrier
Pitbull
more specific
10Implementing superclass Shape and subclass Square
- We will now implement superclass Shape and
subclass Square in C - The rest of the subclasses, i.e., Rectangle,
Triangle, Circle etc. can be implemented similarly
11Shape definition in C ltShape.hgt
class Shape private int x, y
// Shapes anchor point public
Shape() // default constructor
Shape(int x, int y) // parametrized
constructor Shape() //
Destructor int getX() // get x
int getY() // get y void
setX(int x) // set x void setY(int y)
// set y void printInfo() // print
info about the shape
12ltShape.cppgt
// Default constructor ShapeShape()
printf(Shape default constructor\n) x y
1 //end-Shape
// Parametrized constructor ShapeShape(int x,
int y) printf(Shape parametrized constructor.
x d, y d\n, x, y) this-gtx x this-gty
y //end-Shape
// Destructor ShapeShape() printf(Shape
destructor. x d, y d\n, x, y)
//end-Shape
13ltShape.cppgt (cont)
// get y int ShapegetY() return y
//end-getY
// get x int ShapegetX() return x
//end-getX
// set x int ShapesetX(int x) this-gtx x
//end-setX
// set y int ShapesetY(int y) this-gty y
//end-setY
// print info int ShapeprintInfo()
printf(Shape x d, y d\n, x, y)
//end-printInfo
14Subclass Square in CltSquare.hgt
class Square public Shape // means Square
extends Shape private int width
public Square() //
default constructor Square(int x, int y, int
width) // parametrized constructor
Square() // Destructor
void printInfo() // override
Shapes printInfo int getWidth()
// get width void setWidth(int w)
// set width void draw(char ch)
// draw on the screen
15ltSquare.cppgt
// default constructor int SquareSquare()
printf(Square default constructor\n) width
1 //end-Square
// parametrized constructor int
SquareSquare(int x, int y, int w)
printf(Square parametrized constructor\n)
setX(x) // Why not this-gtx x ? setY(y)
// Why not this-gty y ? width w
//end-Square
// destructor int SquareSquare()
printf(Square destructor. width d\n,
width) //end-Square
16ltSquare.cppgt
// get squares width int SquaregetWidth()
return width //end-getWidth
// set squares width to w void
SquaresetWidth(int w) width w
//end-setWidth
// draw the square on the screen void
Squaredraw(char ch) for (int i0 iltwidth
i) for (int j0 jltwidth j)
putchar(ch) //end-for
putchar(\n) //end-for //end-draw
17ltSquare.cppgt
// print info int SquareprintInfo()
printf(Square x d, y d, width d\n,
getX(), getY(), width) //end-printInfo
- A subclass can override a method from the
superclass, thus redefining new behavior - In our example, Square inherits getX, getY, setX,
setY from Shape, but overrides printInfo
18Creating Square objects in C
main() Square square1 new Square()
square1-gtprintInfo() delete square1
printf(-------------------------------\n)
Square square2 new Square(5, 7, 9)
square2-gtprintInfo() delete square2
//end-main
Shape default constructor Square default
constructor Square x 1, y 1, width 1 Square
destructor. width 1 Shape destructor. x 1, y
1 -------------------------------------- Shape
default constructor Square parametrized
constructor Square x 5, y 7, width 9 Square
destructor. width 9 Shape destructor. x 5, y 7
19Shape Object Creation/Deletion
- During object creation, the constructor for the
superclass is called first, followed by the
constructor for the subclass - During object deletion, the destructor for the
subclass is called first, followed by the
destructor for the superclass - When Squares parametrized constructor was used,
Shapes default constructor was called!! - How can we call Shapes parametrized constructor?
20Calling Shapes parametrized constructor from
Squares
// parametrized constructor int
SquareSquare(int x, int y, int w) Shape(x,
y) printf(Square parametrized
constructor\n) width w //end-Square
- When Squares parametrized constructor is called,
we first call the superclass Shapes
parametrized constructor. Then we go inside
Squares constructor and initialize width. - Notice that we do not initialize x and y inside
Squares constructor anymore
21Squares parametrized constructor
main() Square square1 new Square()
square1-gtprintInfo() delete square1
printf(-------------------------------\n)
Square square2 new Square(5, 7, 9)
square2-gtprintInfo() delete square2
//end-main
Shape default constructor Square default
constructor Square x 1, y 1, width 1 Square
destructor. width 1 Shape destructor. x 1, y
1 -------------------------------------- Shape
parametrized constructor Square parametrized
constructor Square x 5, y 7, width 9 Square
destructor. width 9 Shape destructor. x 5, y 7
22Accessing members of superclass
- When implementing printInfo inside Square, we did
not access x or y directly!
// print info int SquareprintInfo()
printf(Square x d, y d, width d\n,
getX(), getY(), width) //end-printInfo
- If we write the following code, the compiler will
complain! It will give an access violation!
// print info int SquareprintInfo()
printf(Square x d, y d, width d\n, x, y,
width) //end-printInfo
23Accessing members of superclass
- This access violation error is because Shapes
x and y were declared private
class Shape private int x, y
// Shapes anchor point public
Shape() // default constructor
Shape(int x, int y) // parametrized
constructor Shape() //
Destructor
- What if you want Shapes subclasses to directly
access x and y, but at the same time protect
x and y from direct outside access? - Obviously we can NOT make x and y public
24protected keyword
- The solution is to make x and y protected
class Shape protected int x, y
// Shapes anchor point public
Shape() // default constructor
Shape(int x, int y) // parametrized
constructor Shape() //
Destructor
- Now you can access x and y directly inside
Shapes subclasses such as Square
// print info int SquareprintInfo()
printf(Square x d, y d, width d\n, x, y,
width) //end-printInfo
25Accessing a subclass using a pointer to
superclass C
- It is possible to access a subclass object using
a pointer to superclass - Using a pointer to superclass, you can invoke
only superclasss methods getX, getY, setX,
setY, printInfo
Square square new Square() Shape shape
NULL square-gtprintInfo() // Can access a
subclass object // using a pointer to
superclass shape square shape-gtsetX(30) shape-
gtsetY(30) square-gtprintInfo() shape-gtprintInfo()
delete square
Shape default constructor Square default
constructor Square x 1, y 1, width 1 Square
x 30, y 30, width 1 Shape x 30, y 30 Square
destructor. width 1 Shape destructor. x 1, y 1
26Accessing a subclass using a pointer to
superclass C
- Observe that when we call printInfo using a
pointer to Shape, Shapes printInfo is run, but
when we call printInfo using a pointer to
Square, Squares printInfo is run. - What if we always want Squares printInfo to be
run, no matter what the type of the pointer is? - That is, even if we use a pointer to Shape, we
want Squares printInfo to run - To make this possible, we have to make printInfo
a virtual function - This is called polymorphism and is the main
pillar of OO programming
27Implementing superclass and Square subclass in
Java
- We will now implement superclass Shape and
subclass Square in Java - The rest of the subclasses, i.e., Rectangle,
Triangle, Circle etc. can be implemented similarly
28ltShape.javagt
class Shape protected int x, y
// Shapes anchor point public Shape()
System.out.println(Shape default constructor)
x y 1 //end-Shape public Shape(int
x, int y) System.out.println(Shape
parametrized constructor) this.x x
this.y y //end-Shape public int
getX()return x public int getY()return y
public void setX(int x)this.x x public
void setY(int y)this.y y public void
printInfo() System.out.println(Shape x
x , y y) //end-printInfo
29ltSquare.javagt
class Square extends Shape private int
width public Square() super() //
Call superclass Shapes default constructor
System.out.println(Square default
constructor) width 1 //end-Square
public Square(int x, int y, int w) super(x,
y) // Call Shapes parametrized constructor
System.out.println(Square parametrized
constructor) width w //end-Square
// Override Shapes printInfo public void
printInfo() System.out.println(Square x
x , y y , width width)
//end-printInfo public int getWidth()return
width public void setWidth(int w)width
w public void draw(char ch)
30Creating Square objects in Java
public static void main(String args) Square
square1 new Square() square1.printInfo()
System.out.println(------------------------------
) Square square2 new Square(5, 7, 9)
square2.printInfo() //end-main
Shape default constructor Square default
constructor Square x 1, y 1, width
1 -------------------------------------- Shape
parametrized constructor Square parametrized
constructor Square x 5, y 7, width 9
31Square constructors in Java
public Square() super() // Call
superclass Shapes default constructor
System.out.println(Square default
constructor) width 1 //end-Square
public Square(int x, int y, int w) super(x,
y) // Call Shapes parametrized constructor
System.out.println(Square parametrized
constructor) width w //end-Square
- By default, Java calls superclasss default
constructor. Despite this, it is good practice to
explicitly call the superclasss default
constructor as the first statement in subclasss
constructor - This is done by super() call
- If you want to call superclasss parametrized
constructor, pass arguments to super
32Accessing a subclass using a pointer to
superclass Java
- It is possible to access a subclass object using
a pointer to superclass - Using a pointer to superclass, you can invoke
only superclasss methods getX, getY, setX,
setY, printInfo
Square square new Square() Shape shape
null square.printInfo() // Can access a
subclass object // using a pointer to
superclass shape square shape.setX(30) shape.s
etY(30) square.printInfo() shape.printInfo()
Shape default constructor Square default
constructor Square x 1, y 1, width 1 Square
x 30, y 30, width 1 Square x 30, y 30,
width 1
33Accessing a subclass using a pointer to
superclass Java
- Observe that no matter what type of pointer we
use, Java always calls Squares printInfo - This means that Java implicitly makes all
subclass methods virtual. Thus, even when you
call printInfo with a pointer to superclass
Shape, it is the subclass Squares printInfo that
gets run - Notice that this is different than C, where the
programmer must explicitly make a method
virtual if s/he wants the subclasss method to
be invoked. Otherwise, the superclasss method
will be invoked.
34Inheritance - Summary
- Given a set of classes, determine the common
properties of these classes and collect them into
a superclass. Then have each class borrow
(inherit) these common properties from the
superclass by extending it. - The main benefits of inheritance are
- Avoids code duplication
- Allows code reuse and easier code maintenance
- Allows polymorphism, which is one of the pillars
of Object Oriented Programming