Inheritance and Polymorphism - California State University San

advertisement
Inheritance
and
Polymorphism
Sahar Mosleh
California State University San Marcos
Page
1
Inheritance
• It is one of the most important feature of object-oriented
programs.
• It allows creation of hierarchical classifications
• You can create a general class and specific classes inherit
the members of a general class
• In java, the class that is inherited is called superclass
• The class that is inheriting is called subclass
• A subclass is a specialized version of a superclass
Sahar Mosleh
California State University San Marcos
Page
2
Simple Inheritance Example
class TwoDShape
{
doublewidth;
doubleheight;
void showDim()
{
System.out.println("Width and Height are " + width + " and " +
height);
};
}
class Triangle extends TwoDShape
{
String style;
double area()
{
return ((width*height) / 2.0);
}
}
void showStyle()
{
System.out.println("Triangle is " + style);
}
Sahar Mosleh
California State University San Marcos
Page
3
class Shapes
{ public static void main(String args[ ])
{
Triangle t1 = new Triangle();
Triangle t2 = new Triangle();
t1.width = 4.0;
t1.height = 4.0;
t1.style = "isosceles";
t2.width = 8.0;
t2.height = 12.0;
t2.style = "right";
Output
-------Info for t1:
Triangle is isosceles
Width and Height are 4.0 and 4.0
Area is 8.0
Info for t2:
Triangle is right
Width and Height are 8.0 and 12.0
Area is 48.0
System.out.println("Info for t1: ");
t1.showStyle();
t1.showDim();
System.out.println("Area is " + t1.area());
System.out.println();
}
}
System.out.println("Info for t2: ");
t2.showStyle();
t2.showDim();
System.out.println("Area is " +t2.area());
System.out.println();
Sahar Mosleh
California State University San Marcos
Page
4
• The superclass is TwoDShape.
• The subclass is Triangle.
• The keyword that makes Triangle to inherit the members of
TwoDShape is extends.
• TwoDShape is a superclass because it defines the attributes of a
“generic” two-dimensional shape such as Square, Triangle, and
so on.
• Then the Triangle class is a specific type of TwoDShape.
Triangle class includes all members of TwoDShape class plus
some specific member (attributes and methods) that is specific
to objects of type Triangle.
• Note that the attributes width and height do not belong to
Triangle class but they are used in the method “area” since they
are inherited by Triangle class.
Sahar Mosleh
California State University San Marcos
Page
5
• The general form of a class declaration that inherits a superclass
is:
Class subclass-name extends superclass-name
{
// body
}
• Several subclasses may inherit from the same superclass
• However, a subclass can only inherit from one superclass
• This is similar to saying a parent can have many children but a
child can only have one parent.
• Subclasses of the same superclass are not related. The only
common feature between them is what they inherit.
Sahar Mosleh
California State University San Marcos
Page
6
class TwoDShape
{
double
width;
double
height;
void showDim()
{
System.out.println(“….”);
};
}
class Triangle extends TwoDShape
{
String style;
double area()
{
……
}
}
Sahar Mosleh
class Rectangle extends TwoDShape
{
boolean isSequence()
{
…..
}
double area()
{
……
}
}
California State University San Marcos
Page
7
• Triangle and Rectangle both inherit the attributes “width” and
“height” and the method “showDim()” from the TwoDShape class
• The method “area()” and attribute “style” belong specifically to
Triangle class
• Further, the methods “isSequence()” and “area()” (the one that is
defined in Rectangle class) belongs to Rectangle class
• The “area()” that is defined in Triangle class has nothing to do with
the “area()” defined in Rectangle class.
Sahar Mosleh
California State University San Marcos
Page
8
Member Access and Inheritance
• Remember the rules of encapsulation property in objectoriented program
• The rule is, a private member of a class can only be
accessed through the methods of that class and not by
members of other classes
• The rule also applies for inheritance. It means when class B
inherits the private members of class A, methods in class B do
not allow to access private members inherited from class A.
Sahar Mosleh
California State University San Marcos
Page
9
class TwoDShape
{
private double width;
private double height;
void showDim()
{
System.out.println("Width and Height are " + width + " and " +
height);
};
}
class Triangle extends TwoDShape
{
String style;
double area()
{
return ((width*height) / 2.0);
}
}
Cannot access a private
members of superclass
void showStyle()
{
System.out.println("Triangle is " + style);
}
Sahar Mosleh
California State University San Marcos
Page
10
• To overcome this limitation, it is possible to create a set of accessor
routines (get() and set() values) for the superclass private members
in order to access them.
class TwoDShape
{
private double width; private double height;
double getWidth(){return width;}
double getHeight(){return height;}
void setWidth(double w) { width = w; }
void setHeight(double h) { height = h; }
void showDim()
{ System.out.println("Width and Height are " + width + " and " + height);};
}
class Triangle extends TwoDShape
{
String style;
double area()
{ return ((super.getWidth()*(super.getHeight())) / 2.0); }
}
void showStyle()
{ System.out.println("Triangle is " + style); }
Sahar Mosleh
California State University San Marcos
Page
11
class Shapes3
{ public static void main(String args[ ])
{
Triangle t1 = new Triangle();
Triangle t2 = new Triangle();
t1.setWidth(4.0);
t1.setHeight(4.0);
t1.style = "isosceles";
t2.setWidth(8.0);
t2.setHeight(12.0);
t2.style = "right";
Output
-------Info for t1:
Triangle is isosceles
Width and Height are 4.0 and 4.0
Area is 8.0
Info for t2:
Triangle is right
Width and Height are 8.0 and 12.0
Area is 48.0
System.out.println("Info for t1: ");
t1.showStyle();
t1.showDim();
System.out.println("Area is " + t1.area());
System.out.println();
}
}
System.out.println("Info for t2: ");
t2.showStyle();
t2.showDim();
System.out.println("Area is " +t2.area());
System.out.println();
Sahar Mosleh
California State University San Marcos
Page
12
Constructors and Inheritance
• It is possible for both subclasses and superclasses to have their
own constructors
• The question is that when an object of subclass is created which
constructor is called?
• Constructor of superclass is called? Or
• Constructor of subclass is called? Or
• Both constructors are called?
• The answer is, when an object of the subclass is created, it has
two portions: the specialized portion and the inherited portion.
• The constructor of the superclass initializes the inherited
attributes and the constructor of the subclass initializes the
specialized attributes. But how?
Sahar Mosleh
California State University San Marcos
Page
13
• In java, it is the job of the subclass constructor to invoke the
superclass constructor
• This is done through the keyword called “super”. (We will see
an example of “super” shortly).
• Therefore, if a subclass does not have any constructor, java
simply invokes the default constructor of the subclasses and
superclasses
• When the superclass does not have constructor, only the
constructor of the subclass is invoked and the default
constructor of superclass is called
• So the only interesting case is to understand the role of “super”
keyword when both subclass and superclass define one or more
constructors
Sahar Mosleh
California State University San Marcos
Page
14
• The subclass can call a constructor defined by its superclass
using the following statement
super (parameter-list);
where parameter-list specifies which constructor of the
superclass should be called
• Consider the next example:
Sahar Mosleh
California State University San Marcos
Page
15
class TwoDShape
{ double width;
double height;
TwoDShape(double w, double h)
{
width = w;
height = h;
}
}
class Triangle extends TwoDShape
{ private String style;
Triangle (String s, double w, double h)
{
super(w,h);
style = s;
}
}
class Shapes
{ public static void main(String args[ ])
{ Triangle t1 = new Triangle(“isosceles”, 4.0, 4.0);
Triangle t2 = new Triangle(“right”, 8.0,12.0);
}
}
Sahar Mosleh
California State University San Marcos
Page
16
Using “super” to Access superclass Members
• There is also another version of “super” that acts like the “this”
keyword
• The “this” keyword refers to the attributes specialized by the
subclass and “super” refers to attributes inherited by the class
• This is used as follows:
super.member
• When member is either a method or an attribute inherited by
the class
• This form of super is most applicable to situations in which
member name of a subclass hides members by the same name
in the superclass
Sahar Mosleh
California State University San Marcos
Page
17
class A
{
int i;
}
class B extends A
{
int i;
B (int a, int b)
{
super.i = a;
i = b;
}
}
void show()
{
System.out.println("i in superclass:
System.out.println("i in subclass:
}
class useSuper
{
public static void main (String args[ ])
{
B subOb = new B(1,2);
subOb.show();
}
}
Sahar Mosleh
" + super.i);
" + i);
Output
--------
i in superclass:
i in subclass:
California State University San Marcos
1
2
Page
18
Method Overriding
• When a method in a subclass has the same name and type
signature as a method in its superclass, the method in the
subclass is said to override the method inherited from its
superclass
• This is different from method overloading where methods have
the same name but their signature (parameter list and return
type) are different
• When an overridden method is called from within a subclass, it
will always refer to the version of the method defined by the
subclass
Sahar Mosleh
California State University San Marcos
Page
19
class A
{
int i, j;
A(int a, int b) { i = a; j = b; }
void show()
{ System.out.println("i and j: " + i + " " + j); }
}
class B extends A
{
int k;
B(int a, int b, int c)
{ super(a, b); k = c; }
void show()
{System.out.println("k: " + k); }
}
class Override
{
public static void main (String args[ ])
{
B subOb = new B(1, 2, 3);
subOb.show(); // THIS CALLS B's SHOW() function
}
}
Sahar Mosleh
California State University San Marcos
Page
20
• Note that when show() method is invoked on an object of type B,
the version of show() inside B overrides the version in A
• If you need to invoke the version of show() inherited in class B,
you need to use the super operator
super.show();
class B extends A
{
int k;
B(int a, int b, int c)
{
super(a, b);
k = c;
}
void show()
{
super.show(); // THIS CALLS A’s show()
System.out.println("k: " + k);
}
}
Sahar Mosleh
California State University San Marcos
Page
21
Polymorphism
• Method overriding forms the basis for the concept of “Dynamic
Method Dispatch” in java.
• Dynamic Method Dispatch is the mechanism by which a call to
an overridden method is resolved at run time rather than at
compile time.
• Java implements run-time polymorphism through Dynamic
Method Dispatch.
• When a reference object of a subclass is assigned to a reference
object of its superclass, the overridden methods get polymorphic
behavior.
• This means, if through the object reference of the superclass
an overridden method is called, java determines which
version of that method to execute based on the type of object
reference assigned to the object reference of the superclass.
Sahar Mosleh
California State University San Marcos
Page
22
class ClassA
{
int x, y;
void show()
{ System.out.println(“This is show() in superclass”);}
}
class ClassB extends ClassA
{
int z;
void show()
{ System.out.println(“This is show() in subclass”);}
}
class Shapes
{ public static void main(String args[ ])
{
ClassA objA = new ClassA();
objA.show();
ClassB objB = new ClassB();
objA = objB;
objA.show();
}
}
Sahar Mosleh
Output
---------This is show() in superclass
This is show() in subclass
California State University San Marcos
Page
23
• After the statement
ClassA objA = new ClassA();
objA.show();
• The show method in classA is called as expected. This is an
example of non-polymorphic behavior because method
invocation can be resolved at compile time
• Now consider the following:
ClassB objB = new ClassB();
objA = objB;
objA.show();
• In this case, the objA reference takes the reference objB. Now
the statement objA.show() will call the show() method
overridden in ClassB.
• This is an example of polymorphic behavior because method
invocation is resolved at run time and not at compile time
Sahar Mosleh
California State University San Marcos
Page
24
Abstract Methods and Abstract Classes
• It is possible to create a superclass that only defines a
generalized form that will be shared by all of its subclasses
• Such a class should be declared as abstract
• The abstract class determines the nature of the methods that the
subclasses must implement but does not itself provide an
implementation for some of its methods
• We really should make a class as abstract if the class is unable
to create a meaningful implementation for a method
Sahar Mosleh
California State University San Marcos
Page
25
• Also, it is possible to make a method as an abstract method by
specifying abstract type modifier.
• An abstract method contains no body and therefore not
implemented by the superclass
• Therefore, a subclass must override it. It cannot simply use the
version defined in the superclass
• The general form of declaring an abstract method is:
abstract type name (parameter-list);
• Note that no body for the method is presented
• The abstract method can only be applied to normal methods and
not to static methods or constructors
Sahar Mosleh
California State University San Marcos
Page
26
• To make a class abstract, we need to precede its class
declaration with the abstract modifier.
abstract class classA
{
……
}
• It is not possible to create an object of an abstract class.
• It is only possible to create object reference for an abstract class
for the purpose of polymorphism
• It is important to remember that when a subclass inherits an
abstract class, it must implement all of the abstract methods in
the superclass
Sahar Mosleh
California State University San Marcos
Page
27
abstract class TwoDShape
{
private double width; private double height; private String name;
TwoDShape() { width = height = 0.0; name = "null"; }
TwoDShape(double w, double h, String n) {width = w; height = h; name = n;}
double getWidth(){return width;} void setWidth(double w) { width = w; }
double getHeight(){return height;}void setHeight(double h) { height = h; }
void showDim()
{System.out.println("Width and Height are " + width + " and " + height);};
abstract double area(); // Now area() is abstract
}
class Triangle extends TwoDShape
{
private String style;
Triangle ( ) { super(); style = "null";}
Triangle(String s, double w, double h){ super(w,h, "triangle"); style = s; }
double area(){return (getWidth()*getHeight())/2.0;}
}
Sahar Mosleh
California State University San Marcos
Page
28
class AbsShape
{ public static void main(String args[ ])
{
double TheArea;
//THE NEXT STATEMENT PRODUCES COMPILE
//ERROR BECAUSE IT IS NOT POSSIBLE TO INSTANTIATE
//AN OBJECT FROM AN ABSTRACT CLASS
/*TwoDShape shape = new TwoDShape(); */
TwoDShape shape1; //THIS IS OK. CAN CREATE a REFERENCE
//TO AN ABSTRACT CLASS
Triangle t1 = new Triangle("right", 8.0, 12.0);
shape1 = t1;
t1.showDim();
//showDim DOES NOT HAVE TO BE
//OVERRIDDEN BECAUSE IT IS NOT abstract
TheArea = shape1.area(); //ABSTRACT METHOD area() HAS TO
//BE OVERRIDDEN BECAUSE IT IS AN
//ABSTRACT METHOD
System.out.println("The area of the triangle is: " + TheArea);
}
}
Sahar Mosleh
California State University San Marcos
Page
29
Using Final
• Although method overriding and inheritance are very powerful
tools, in some occasions programmers may like to prevent them
for some special classes.
• For example, you may have a class that controls configuration
of some hardware devices and you do not want any
polymorphism attached to any methods of this class
• Simply attach “final” modifier at the start of the class
declaration
final class classA
{
….
}
Sahar Mosleh
California State University San Marcos
Page
30
• Further, methods declared as final cannot be overridden
• Consider the following example:
class classA
{
final void meth()
{
System.out.println(“This is a final method”);
}
}
class classB extends ClassA
{
void meth()
{ // THIS PRODUCES COMPILE ERROR
System.out.println(“illegal”);
}
}
• Because meth() is declared final, it cannot be overridden in
ClassB. If you attempt to do so, a compile-time error will result.
Sahar Mosleh
California State University San Marcos
Page
31
• In general, by making a method to be a final method, we stop
that method from being overridden.
• If you make a class final, we stop that class from being
inherited
• If an attribute is declared final, that attribute is initialized at
class level and its value cannot be changed
Sahar Mosleh
California State University San Marcos
Page
32
class ErrMsg
{
final int OUTERR = 0;
final int INERR = 1;
final int DISKERR = 2;
final int INDEXERR = 3;
String msg[ ] = {"Output Error", "Input Error",
"Disk Full", "Index Out-Of-Bounds"};
String getErrorMsg(int i)
{ if (i>=0 && i<msg.length)
return msg[i];
else
return "Invalid Error Code";
}
}
class FinalDemo2
{ public static void main(String args[])
{
ErrMsg err = new ErrMsg();
System.out.println(err.getErrorMsg(err.OUTERR));
System.out.println(err.getErrorMsg(err.DISKERR));
}
}
Sahar Mosleh
California State University San Marcos
Page
33
Download