Sei sulla pagina 1di 35

Inheritance vs.

aggregation
There are two ways to reuse ( ‫ ) שימוש חוזר‬the existing classes, namely
aggregation (‫ )הכלה‬and inheritance (‫)ירושה‬.

public class Circle


{
private Point center; // another object ! With aggregation we create a new class,
private double radius; which is composed of existing classes.
// constructor
public Circle(Point center, double radius )
{
this.center = center;
this.radius=radius;
}
public Point getCenter()
{
return this.center; With inheritance we create a new class,
}
public Point getRadius()
which is based on existing class, with
{ some modifications.
return this.radius;
}
// rest methods

1
Inheritance (‫)ירושה‬
In OOP we often organize classes in hierarchy (‫ )היררכיה‬to avoid
duplication and reduce redundancy.
The classes in the lower hierarchy inherit (‫ )ירש‬all the variables
(attributes) and methods from the higher hierarchies.
Redundancy can be greatly reduced or eliminated as these common
variables and methods do not need to be repeated in all the
subclasses.
Person

Student Employee Lecturer

2
Inheritance - example
public class Person
{
...
} //person

public class Student extends Person


{
...
} //student

public class Employee extends Person


{
...
} //employee

public class Lecturer extends Person


{
...
} // lecturer
3
Inheritance (‫ – )ירושה‬definitions
• In the Java language, classes can be derived( ‫( נגזר‬from other classes,
thereby inheriting fields and methods from those classes.
• Inheritance is the process of deriving a new class from an existing one.
• The main purpose of inheritance is to reuse (‫)שימוש חוזר‬existing
software.
When you want to create a new class and there is already a class that
includes some of the code that you want, you can derive your new class
from the existing class. In doing this, you can reuse the fields and
methods of the existing class without having to write (and debug!) them
yourself.
• A class that is derived from another class is called a subclass
or child class (‫ תת מחלקה‬/ ‫ )מחלקה נגזרת‬.
• The class from which the subclass is derived is called a superclass or
a parent class ( ‫ מחלקת בסיס‬/ ‫ )מחלקת על‬.
• Inheritance is a one-way street.That is, a subclass can access public
methods of the superclass, but the superclass cannot accsess methods
of the subclass.
4
Inheritance – classes Student and Mstudent

Note : subclass is not a “subset” of a superclass.


It is because a subclass inherits all the variables and methods of the superclass ,in
addition, it extends the superclass by providing more variables and methods.

Student
Superclass - a class in
the upper hierarchy

calcTuition() Tuition = numOfCourses * coursePrice

Mstudent
Subclass - a class in
the lower hierarchy

calcTuition() Tuition = numOfCourses * coursePrice - stipend 5


Inheritance – class Student
public class Student {
private static final int COURSE_PRICE = 1000; // let’s assume
private String name;
private int id;
private int numOfCourses;
public Student( int id, String name, int numOfCourses) // constructor
{
this.name = name;
this.id = id;
this. numOfCourses = numOfCourses;
}
// getter and setter methods
public int calcTuition()
{
return this.numOfCourses*COURSE_PRICE;
}
// rest methods
6
Inheritance – class Mstudent
public class Mstudent {
private static final int COURSE_PRICE = 1000;
private String name;
private int id;
private int numOfCourses;
private int stipend; // add new attribute !
public Mstudent( int id, String name, int numOfCourses, int stipend)
{
this.name = name;
this.id = id;
this. numOfCourses = numOfCourses;
this.stipend = stipend;
}
// getter and setter methods
public int calcTuition()
{
return this.numOfCourses*COURSE_PRICE – stipend;
}
// rest methods
7
class Mstudent
public class Mstudent extends Student
{ Childe class MStudent derived from
private int stipend; parent class Student.
public Mstudent( int id, String name, int numOfCourses ,int stipend)
{
super(id, name, numOfCourses); A parent constructor can be
this.stipend = stipend; invoked using the super reference.
}
public int calcTuition()
{
return super.calcTuition() - stipend;
}
Using the super reference we can
} accsess a parent’s class methods.
// rest methods

8
Mstudent - test
public static void main(String[ ] args) {
System.out.print( “Enter student's id: “ );
int id=reader.nextInt();
System.out.print( “Enter student's name: ”);
String name=reader.next();
System.out.print( “Enter the number of courses” );
int num =reader.nextInt();
System.out.print( “Enter student's stipend: “ ); Creation subclass
int stipend=reader.nextInt();
Mstudent s1 = new Mstudent(id, name, num, stipend);
System.out.println( “Tuition= "+ s1.calcTuition());
System.out.print( “Enter new student's stipend: “ );
stipend=reader.nextInt();
Subclass method Overriding
s1.setStipend(stipend);
System.out.println( “New tuition= "+ s1.calcTuition()); }
Mstudent - test,cont.

The output produced by this program is:


We assume, that course price = 1000

Enter student's id: 12345


Enter student's name: David
Enter the number of courses: 5
Enter student's stipend: 1000

5 x 1000 - 1000
Tuition= 4000
Enter new student's stipend: 2000 5 x 1000 - 2000
New tuition= 3000

10
Overriding (‫)דריסת שיטת אב‬
• Method overriding is similar to method
overloading(‫)העמסה‬, with a small difference. In
overriding, a method in a parent class is overridden in
the child class.
• The method in the child class will have the same
signature as that of the parent class. Since the method
in the child class has the same signature & name as the
method of its parent class, it is termed as overriding.
• When an overridden method is called from within a
subclass, it will always refer to the version of that method
defined by the subclass. The version of the method
defined by the superclass will be hidden.

11
Overriding - example
public class A {
int a, b;
public A(int a, int b) { // A class constructor
this.a = a;
this.b = b;
}
public void show() // display a and b
{
System.out.println( “ a and b: " + this.a + “ " +this.b);
}
} //class A
Method overriding occurs only
public class B extends A {
when the names and the type
int c;
public B(int a, int b, int c) { // B class constructor signatures of the two methods
super(a, b); are identical.
this.c = c;
}
public void show() // display c – this overrides show() method in A
{
System.out.println(“c: " + this.c);
}
} //class B
12
Overriding - testing
public static void main(String args[ ])
{
B subOb = new B(1, 2, 3);
subOb.show(); // this calls show() in B
}
The output produced by this program is shown here:
c: 3

▪ When show( ) is invoked on an object of type B, the version of


show( ) defined within B is used. That is, the version of show( ) inside
B overrides the version declared in A.
▪ If you wish to access the superclass version of an overridden function,
you can do so by using super.

13
Overriding (using the super)
public class B extends A {
int c;
public B(int a, int b, int c) { //constructor
super(a, b);
this.c = c; }
public void show() {
super.show(); // this calls A's show()
System.out.println(“c: " +this.c); public static void main(String args[ ])
} {
} B subOb = new B(1, 2, 3);
subOb.show(); // this calls show() in A
}

The output produced by this program is shown here:

a and b: 1 2
c: 3
14
Using the super – class Box
public class Box {
private double width;
private double height;
private double depth;
Box(Box ob) {
this.width = ob. width;
Box copy constructor 1
this.height = ob.height;
this.depth = ob.depth; }
Box(double w, double h, double d) {
this.width = w;
this.height = h; Box constructor 2
this.depth = d; }
Box () {
this.width = -1;
this.height = -1; Box default constructor 3
this.depth = -1; }
Box(double len) {
this.width = len; Cube constructor 4
this.height = len;
this.depth = len; }
double volume () {
Box volume calculating
return this.width * this.height * this.depth; }
15
} // class Box
Using the super – class BoxWeight
class BoxWeight extends Box {
double weight; // box weight
// copy constructor 1
BoxWeight(BoxWeight ob) {
super(ob); // call superclass copy constructor
this.weight = ob.weight; }
// constructor 2
BoxWeight(double w, double h, double d, double m) {
super(w, h, d) ; // call superclass constructor
this.weight = m; }
// default constructor 3
BoxWeight() {
super (); // call superclass default constructor
this.weight = -1; }
// cube constructor 4
BoxWeight(double len, double m) {
super(len); // call superclass cube constructor
this.weight = m; }
} // class BoxWeight 16
Using the super – DemoSuperTest
public class DemoSuper {
public static void main(String args[ ]) {
BoxWeight mybox1 = new BoxWeight(10, 20, 15, 34.3);
BoxWeight mybox2 = new BoxWeight(2, 3, 4, 0.076);
BoxWeight mybox3 = new BoxWeight ();
BoxWeight mycube = new BoxWeight (3, 2);
BoxWeight myclone = new BoxWeight(mybox1);
double vol= mybox1.volume ();
System.out.println("volume myboxl = " + vol) ;
System.out.println("weight myboxl = " + mybox1.weight);
vol = mybox2.volume();
System.out.println("volyme mybox2 = " + vol);
System.out.println("weight of mybox2 = " + mybox2.weight);
vol = mybox3.volume();
System.out.println("volume myboxЗ = " + vol) ;
System.out.println("weight myboxЗ = " + mybox3.weight);
vol = myclone.volume();
System.out.println("volume myclone = " + vol);
System.out.println("weight myclone = " + myclone.weight);
vol = mycube.volume ();
System.out.println("volume mycube = " + vol);
System.out.println("weight mycube = " + mycube.weight);
} // main
17
} // class DemoSuperTest
DemoSuperTest - output
volume mybox1 = 3000.0
weight mybox1 = 34.3
volume mybox2 = 24.0
weight mybox2 = 0.076
volume myboxЗ = -1.0
weight myboxЗ = -1.0
volume myclone = 3000.0
weight myclone = 34.3
volume mycube = 27.0
wight mycube = 2.0
18
Overriding opposite overloading
public class A {
int a, b;
public A(int a, int b) { // A class constructor
this.a = a;
this.b = b; }
public void show() // display a and b
{
System.out.println( “ a and b: " + this.a + “ " +this.b);
}
} // class A
public class B extends A {
int c;
public B(int a, int b, int c) { // B class constructor
super(a, b);
this.c = c;
}
public void show(String msg) // overload show() from superclass
{
System.out.println( msg + this.c);

}
} // class B 19
Overriding oppozite overloading
public static void main(String args[ ]) {
B subOb = new B(1, 2, 3);
subOb.show("This is k: "); // this calls show() in B
subOb.show(); // this calls show() in A
}

The output produced by this program is shown here:


This is k: 3
a and b: 1 2

The version of show( ) in B takes a string parameter.


This makes its type signature different from the one in A, which
takes no parameters. Therefore, no overriding (or name hiding)
takes place.

20
Polymorphism in Java
Object Oriented Programming (OOP) is actually classified by three
main principles:

1) Encapsulation
2) Inheritance
3) Polymorphism

• Polymorphism ( ‫) רב צורתיות‬is the ability of an object to take on


many forms.
• Polymorphism word comes from ancient Greek where poly means
many so polymorphic are something which can take many form.
• In programming languages polymorphism is the capability of an
action or method to do different things based on the object that it is
acting upon.
• In this course we learn two form of polymorphism:
compile-time polymorphism and run-time polymorphism.
21
Polymorphism – what it is

22
Polymorphism – what it is not

Jump

23
Compile – time polymorphism
This form of polymorphism is called compile-time polymorphism because the
compiler knows after the compile to the byte code which of the add methods it will
execute.

public class OverLoadTest public class DemoClass


{ {
public static void main(String [] args) public int add(int x, int y)
{ {
System.out.println(add(2,5)); return x + y;
System.out.println(add(2,5,9)); } // end add 2 int parameters
System.out.println(add(3.07,10)); public int add(int x, int y, int z)
} {
} return x + y + z;
} // end add 3 int parameters
public int add(double x, int y)
{
return (int )x + y;
Compile-time polymorphism is
} // end add double and int parameters
achieved with overloaded methods.
24
Run – time polymorphism

• The run-time polymorphism in OOP occurs when a


parent class reference is used to refer to a child class
object.
• This form of polymorphism called sometimes dynamic-
binding (‫)בחירת השיטות המתאימות נעשית תוך כדי הריצה‬.
• At compile time the compiler does not know which of the
methods are to be executed. It will not know that until run
time: time of real program executing.
• Run-time polymorphism is achieved through with
overridden methods ( while compile – time polymorphism
is achieved with overloaded methods).

25
Run-time polymorphism - example
public class Person {
public void sayHi)( {
System.out.println("Hello there!");
}
} //class Person

public class Student extends Person {


public void sayHi)( {
System.out.println("Hello there! I’m a student.");
}
} //class Student
public class Lecturer extends Person {
public void sayHi)( {
System.out.println("Hello there! I’m a lecturer.");
}
} // class Lecturer
26
Run – time polymorphism implementation
public static void main(String[] args))
{ ‫ בחירת השיטות‬- Dynamic Binding
.‫המתאימות נעשית תוך כדי הריצה התוכנית‬
Person p1 = new Person)(;
Person p2 = new Lecturer)(;
Dynamic binding is the ability of a
Person p3 = new Student )(; program to resolve references to
p1.sayHi)(; subclass methods at runtime.
p2.sayHi)(;
p3.sayHi(); The type of the reference variable
} //main would determine the methods that it
can invoke on the object.
This will produce:
Method overriding allows Java to
Hello there! invoke method based on a particular
Hello there! I'm a lecturer object at run-time instead of
Hello there! I'm a student declared type while coding.

27
Polymorphism – example2
Shape
color
Superclass - a class in
getArea() the upper hierarchy
toString()

Note: we have a problem on


Rectangle Triangle writing the getArea() method
length base in the Shape class!
width height
getArea() getArea()
toString() toString()

Subclasses - a classes in the low hierarchy 28


Class Shape
public class Shape
{
private String color;
public Shape(String color)
{
this.color=color;
The area in the Shape class
} // constructor
cannot be computed unless
public double getArea() the actual shape is known!
{
System.out.println(“Shape unknown! Cannot compute area”);
return 0;
} //need a return to compile the program
public String toString()
{
return ( “Shape color is” + this.color );
}
} // class Shape

29
Class Rectangle
public class Rectangle extends Shape
{
private int length;
private int widht;
public Rectangle(String color, int length, int width)
{
super(color);
this.length=length;
this.width=width;
} // constructor
public double getArea()
{
return this.length * this.width;
}
public String toString()
{
return ( “length= ” + this.length + “width= “+ this.width );
}
} // class Rectangle

30
Class Triangle
public class Triangle extends Shape
{
private int base;
private int height;
public Triangle(String color, int base, int height)
{
super(color);
this.base=base;
this.height=height;
} // constructor
public double getArea() {
return 0.5*this.base * this.height;
}
public String toString()
{
return ( “base= ” + this.base + “height= “+ this.height );
}
} // class Triangle

31
Class Shape implementation -1
public class TestShape1
{
public static void main(String [ ] args) In this program all references are
{ from the superclass Shape.
Shape s1 = new Rectangle(“red”, 4, 5);
System.out.println(s1);
System.out.println(“ Area is “+ s1.getArea());
Shape s2 = new Triangle(“green”, 3, 6);
System.out.println(s1);
System.out.println(“ Area is “+ s2.getArea());
} // main This will produce:
} // class TestShape1
length= 4 width= 5
Area is 20.0
length= 4 width= 5
Area is 9.0 32
Class Shape implementation - 2
public class TestShape2
{
public static void main(String [] args)
{ Shape [ ] arr = new Shape[2];
arr[0] = new Rectangle(“red”, 4, 5);
arr[1] = new Triangle(“green”, 3, 6);
for( int i=0; i<2; i++)
System.out.println(“ Area is “+ arr[ i ]. getArea());
} // main
} // class TestShape2
This will produce:
Area is 20.0
Area is 9.0
Class Shape extending
We can extend our program easily by adding in more subclasses as
Circle, Square, etc. with ease.

Shape
color
getArea()
toString()

Rectangle Triangle Circle Square


length base radius length
width height getArea() getArea()
getArea() getArea() toString() toString()
toString() toString() 34
Class Shape extending cont.
Shape [ ] arr = new Shape[N];
arr[0] = new Rectangle(“red”, 4, 5);
arr[1] = new Triangle(“green”, 3, 6);
arr[2] = new Circle(“blue”,7);
arr[3] = new Square(“black”,11);
.
.
.
for( int i=0; i<N; i++)
System.out.println(“ Area is “+ arr[ i ]. getArea());

NOTE: Inheritance is a one-way street !

Rectangle r1 = new Shape (“red”, 4, 5);

35

Potrebbero piacerti anche