OOP: Polymorphism

you are watching: OOP: Polymorphism here hiddentracks.org


POLYMORPHISM,
INTERFACES, COMPOSITION

TOPICS

·  Polymorphism

·  Abstract
Classes

·  Interfaces

·  Composition

·  Programming Samples

·  Interfaces:
Figure, Circle, Rectangle, Triangle

·  Composition:
Person, Date, PersonalInfo

OUTLINE

1. Polymorphism
 

·  Definition: Polymorphism = A
basic principle of OOD defined as the ability to use the same expressions to
denote different operations (in other words, the ability to associate multiple
meanings to the same method name. )

·  Polymorphism is a word of Greek origin
that means having multiple forms.

·  Reminder (Inheritance):

·  An object of a subclass class has the type of the subclass
class, and it also has the type of the superclass.

·  An object of a derived class can be plugged in as a parameter
in place of any of its ancestor classes.

·  In a class hierarchy, several methods may have the same name
and the same formal parameter list. Moreover, a reference variable of a class
can refer to either an object of its own class or an object of its subclass.
Therefore, a reference variable can invoke a method of its own class or of its subclass(es).

·  Polymorphism is
implemented through a mechanism known as late binding, dynamic binding or
run-time binding
–> refer to the situation where the method that gets
executed is determined at execution time, not at compile time.

·  Definition: Binding = Associating
a method definition with its invocation.

·  In early binding, a methods definition is associated
with its invocation when the code is compiled. In late binding, a method’s
definition is associated with the method’s invocation at execution time. In
late binding the method invoked is determined by the type of object to which
the variable refers, NOT by the type of the reference variable.

·  NOTE: Except for a few special
cases, Java uses late binding for all methods. Java uses late binding for all
methods except for:

·  final
methods (you can
declare a method as
final by using the keyword final. If a method of a class is
declared
final, it cannot be overridden with a new definition in a derived
class. You might wish to make a method
final if it has an implementation
that should not be changed and it is critical to the consistent state of the
object. Methods called from constructors should generally be declared as
final. If a constructor calls a
non-final method, a subclass may redefine that method with unexpected/unwanted
results. NOTE: You can also declare a
class as
final using the keyword final. If a class is declared final, then no other class can be
derived from this class. This is particularly useful, for example, when
creating an immutable class)

·  private methods

·  static methods.

·  In a well designed OOP program, most
methods will communicate with a superclass reference and let late binding and
polymorphism determine which method to call. Such a program is called extensible
because you can add new functionality by deriving new classes from the
superclass without changing existing code.

·  Using late binding Example: method toString. If an appropriate toString method is defined for a
class, then an object of that class can be output using 
System.out.println
(
);
as in these
examples:

Point somePoint
= new Point( );

System.out.println(somePoint);
Box b = new Box();
System.out.println(b);

These
statements work because of late binding. Because of late binding, the
toString method from the Point class is used, not the toString from the Object class. Same for Box.

·  Understanding Polymorphism (Example):

public
class Class_1 {

    public void method_1() {
        System.out.println(“Class_1 output from
method_1”);


    }

    public void method_2() {
       
System.out.println(“Class_1 output from
method_2”);

    }

    public String toString() {
       
return “toString() from Class_1″;

    }

}

public class Class_2 extends
Class_1 {

   
public void method_2() {

       
System.out.println(“Class_2 output from
method_2”);

    }

    public String toString() {
       
return “toString() from Class_2. No method_1 in
Class_2. “;

    }

}

public class Class_3 extends
Class_1 {

   
public void method_1() {

       
System.out.println(“Class_3 output from
method_1”);

    }

    public String toString() {
       
return “toString() from Class_3. No method_2 in
Class_3.“;

    }

}

public class Class_4 extends
Class_3 {

   
public void method_2() {

       
System.out.println(“Class_4 output from
method_2”);

    }

    public String toString() {
       
return “toString() from Class_4. No method_1 in
Class_4.“;

    }

}

public class Test_Polymorphism {
   
public static void main(String[] arg) {

       
Class_1 [] someObj = {new Class_1(), new Class_2(),
new Class_3(), new Class_4()};

       
System.out.println(“Class_1 = superclass:
method_1, method_2, toString“);

       
System.out.println(“Class_2 = subclass of
Class_1: method_2, toString“);

       
System.out.println(“Class_3 = subclass of
Class_1: method_1, toString“);

       
System.out.println(“Class_4 = subclass of
Class_3: method_2, toStringn”);

       
for(int i = 0; i < someObj.length; i++) {

           
System.out.println(someObj[i]);//toString()
invoked

           
someObj[i].method_1();


           
someObj[i].method_2();


           
System.out.println();

       
}

    }

}
OUTPUT:

Class_1 = superclass:
method_1, method_2, toString

Class_2 = subclass of
Class_1: method_2, toString

Class_3 = subclass of
Class_1: method_1, toString

Class_4 = subclass of
Class_3: method_2, toString

toString() from Class_1
Class_1 output from method_1

Class_1 output from
method_2

toString() from Class_2. No method_1
in Class_2.

Class_1 output from
method_1

Class_2 output from
method_2

toString() from Class_3. No method_2
in Class_3.

Class_3 output from
method_1

Class_1 output from
method_2

toString() from Class_4. No method_1
in Class_4.

Class_3 output from
method_1

Class_4 output from method_2

2.
Introduction to Abstract Classes:

 

·  Definition: Abstract method = a
placeholder for a method that will be fully defined in a subclass. In other
words, the definition of the method is postponed – the abstract method has
only the heading without the body. The heading of an abstract method contains
the reserved word
abstract and ends with a semicolon in
place of its body. The body of the method (the implementation) is defined in
the derived classes. NOTE: Abstract
methods cannot be private.

·  Examples:

public
abstract void someMethod(int
x, int y);

public abstract int computeSomething(int[] someArray);
public abstract void movePoint(double
dX, double dY);

·  Definition: Abstract class = a class that is declared
with the reserved word
abstract in its heading. Also, any
class that contains an abstract method is called an abstract class (see [3]
below). A class that has no abstract methods is called a concrete class.

·  Rules and facts about abstract
classes:

1.
An abstract class can contain instance variables, constructors, finalizer, and nonabstract
methods.
2. An abstract class can contain abstract method(s).
3. If a class contains an abstract method, then the class must be declared
abstract.
4. If a subclass of an abstract class adds to or does not define all of the
abstract methods, the subclass is abstract also, and must add
abstract
to its modifier.

5. Because an abstract class is not fully defined, you cannot create objects of
the abstract class type. Although an object of an abstract class cannot be
created, it is perfectly fine to have a parameter of an abstract class type.
6. You can create objects of a subclass of an abstract class only if the
subclass gives the definitions of all the abstract methods of the superclass.

·  Abstract classes are used as superclasses
from which other subclasses within the same context can be derived. Abstract
classes can only be used to derive more specialized classes. They can be used
to force subclasses to provide certain methods.

·  NOTE: All of the methods in an
interface (see Interfaces below) are implicitly
abstract, so the
abstract modifier is not used with
interface methods (it could be; it’s just not necessary).

3. Interfaces
 

·  Reminder: In Java a class can be
derived from only one existing class because Java does not support multiple
inheritance.

·  Reminder: If a class contains an
abstract method, then the class must be declared abstract. Also, because an
abstract class is not fully defined, you cannot create objects of the abstract
class type.

·  Definition: Interface = a class that contains only
abstract methods and/or named constants. An interface is a mechanism used by
unrelated objects in order to interact with each other – like a protocol.

·  Java allows a class to implement more than one interface –>
this is how Java implements multiple inheritance, which is not true multiple
inheritance.

·  If a class implements an interface, it must provide
definitions for each of the methods of the interface; otherwise, you cannot
create objects of that class type (just like with abstract classes).

·  An interface is a reference type, similar to a class, that can
contain only constants, method signatures, and nested types (no method bodies.)

·  Interfaces cannot be instantiated; they
can only be implemented by classes or extended by other interfaces.

·  Basically, an interface is a list of
methods that classes promise to implement (protocol). While inheritance gives
you an is-a
relationship and code-sharing, an interface gives you an is-a
relationship without code sharing.

·  Defining an interface is similar to creating a new class. To use an
interface, you have to write a class that
implements the interface. When a class
implements an interface, it provides a method body for each of the methods
declared in the interface.

·  Interface declaration, general
syntax
:

public
interface InterfaceName {

    public Type method1(Type param1, Type
param2…);

    public Type method2(Type param1, Type
param2…);

    …
}

·  A class can declare that it implements an interface. This
means the class contains an implementation for each of the abstract methods in
that interface. Otherwise –> compiling error!

·  Implementing an interface, general
syntax
:

public
class ClassName implements InterfaceName
{

    definition/implementation for method1
    definition/implementation fpr method2
    …
}

·   Example:

public interface Employee {
    public String getEmployeeID();
    public double getSalary();
    public void setEmployeeID(String id);
    public void setSalary(double salary);
}

public class Faculty implements Employee {…}

·  NOTE: A class can extend the
definition of only one class (single inheritance), but it  can implement
any number of interfaces. In fact, a class can both extend another class
(inheritance) and implement one or more interfaces.  Example:

public class Person {…}

public interface Employee {
   
public String getEmployeeID();

   
public double getSalary();

   
public void setEmployeeID(String id);

   
public void setSalary(double salary);

}

public class Faculty extends Person implements
Employee {…}

·  Why using interfaces?

·  Can declare a common set of methods that one or more classes
are required to implement.

·  Can provide access to an object’s programming interface without
revealing the details of its class.

·  Can provide a relationship between unrelated classes without
imposing an unnatural class relationship.

·  NOTE: Most likely, you will need
to write your own interfaces when writing fairly complex applications. However,
Java standard packages include a few interfaces that are used very often.

·  Take a look at the Figure interface and the
classes Circle, Rectangle and Triangle implementing it.

·  Why do both interfaces and abstract classes exist in Java? An
abstract class can do everything an interface can do and more. So why would
someone ever use an interface? Answer: Java has single inheritance (a class can
extend only one superclass, but can implement many interfaces). Having
interfaces allows a class to be part of a hierarchy (polymorphism) without
using up its inheritance relationship.

4. Composition
 

·  Effective software development relies
on reusing existing code. The goal with OOP languages is to reuse classes
without changing the code within the class – one OOP technique for code reuse
is known as composition.

·  Definition: Composition = another way to relate two
classes. In composition, one or more members of a class are objects of another
class type. In other words, composition (aggregation) = the use of classes as
instance variables in the definition of another class.

·  Composition is a “has-a”
relation. Example: “Every person has a last name” ,
“Every point has a x-coordinate”

·  To understand how
composition works, take a look at the program sample below.

·  Making a copy of an
object requires a special method called a copy constructor.

·  Definition: Copy constructor = a constructor
with a single argument of the same type as the class. The copy constructor
should create an object that is a separate, independent object, but with the
instance variables set so that it is an exact copy of the argument object.

·  Example of a copy
constructor for a class with primitive type instance variables – just copy the
primitive variables using the assignment operator. In class
Date:

public
Date(Date original) {


    if(original == null)  {
        System.out.println(“Fatal error for this Date.”);
        System.exit(0);
    }
    month = original.month;
    day = original.day;
    year = original.year;
}

·  Because of composition, the technique used with Date will not work
correctly with class
PersonalInfo. The actual copy constructor
for the
PersonalInfo class is a safe version that
creates completely new and independent copies of
fullName and birthDate, and therefore, a completely
new and independent copy of the original
PersonalInfo object.

public
PersonalInfo(PersonalInfo
original) {

    if(original == null)  {
        System.out.println(“Fatal error.”);
        System.exit(0);
    }
    //Class Person has to have
a copy constructor!


    //Without a copy
constructor in Person, the next statement will not work

    fullName = new Person(original.fullName);
    //Class Date has to have a
copy constructor!


    //Without a copy
constructor in Date, the next statement will not work

    birthDate = new
Date(original.birthDate);

    //personId
is a primitive type –> use assignment

    personID = original.personID;
}

·  NOTE In order to define a correct
copy constructor for a class that uses composition, copy constructors must
already be defined for the instance variables’ classes (e.g.
Date, Person)

·  Arrays and Composition: Just as a class type can be
used as an instance variable, arrays can also be used as instance variables. We
can define an array with a primitive base type

private
double[ ] temps = new double[MAX];

 or an array with a class base type:

private
Date[ ] someDates = new Date[MAX];

·  Example:

public
double[ ] getTemps( ) {

    return temps; //what
is returned here???


}

·  ANSWER: The method will return a
reference to the array
temps –> should return a reference to a deep copy of the
private array object.

·  Corrected version:

public
double[ ] copyTemps( ){

    double[ ] copy = new double[temps.length];
    for(int i = 0; i < temps.length;
i++)


        copy[i] = temps[i];
    return copy;
}

·  If a private instance variable is an array that has a class as
its base type (an array of objects), then you must make copies of each class
object in the array, as in the next Example:

public
Date[ ] copyDates( ) {

    Date[ ] copy = new Date[someDates.length];
    for(int i = 0; i < someDates.length;
i++)


        copy[i] = new Date(someDates[i]);

    return copy;
}

Programming
Samples:

Interface: Figure.
Classes: Circle, Rectangle, Triangle

//
A general interface for all Figure classes.

public interface Figure {
   
public double getArea();

   
public double getPerimeter();

    public
int getSideCount();

   
public boolean equals(Object obj);


   
public String toString();

}

//Circle
class, implementing Figure

//A
Circle object represents a pair of (x, y) coordinates

//for
the center of the circle, and its radius.

public class Circle implements
Figure {

   
private int x;

   
private int y;

   
private double radius;

   
//Default constructor

   
public Circle() {

       
x = 0;

       
y = 0;

       
radius = 1;

    }

   
// Alternate constructor

   
public Circle(int x1, int y1) {

       
x = x1;

       
y = y1;

       
radius = 0;

    }

   
// Alternate constructor

   
public Circle(int x1, int y1, double r) {

       
x = x1;

       
y = y1;

       
radius = r;

    }

   
//set center position

   
public void setCoord(int x1, int
y1) {

       
x = x1 >= 0? x1: 0;

       
y = y1 >= 0? y1: 0;

    }

   
//set radius

   
public void setRadius(double r) {

       
radius = r;

    }

   
// Calculate perimeter

   
public double getPerimeter() {

       
return 2 * radius * Math.PI;

    }

   
// Calculate area

   
public double getArea() {

       
return Math.pow(radius, 2) * Math.PI;


    }

   
// Returns the number of sides a circle has (0).

    public int getSideCount()
{

       
return 0;

    }

   
// Accessor methods

   
public int getX() {

       
return x;

    }

    public int getY()
{

       
return y;

    }

    public double getRadius() {

       
return radius;

    }

   
// Method toString

   
public String toString() {

       
return “center at (” + x + “, ” + y + “), radius =
” + radius;

    }

    public void print() {
       
System.out.print(“The center is at (” + x +
“, ” + y + “)”);

       
System.out.println(“. The radius is ” +
radius);

    }

   
// Compare for equality

   
public boolean equals(Object
obj) {

       
if (obj instanceof Circle)
{

           
Circle otherCircle = (Circle) obj;


           
return (this.x == otherCircle.x
&& this.y == otherCircle.y
&& this.radius == otherCircle.radius);


       
}

       
else   // not a Circle object


           
return false;

    }

 

   
// Shift the location of this circle by the given amount.

    public void translate(int dx, int dy) {
       
if (x + dx < 0 || y + dy < 0) {

           
throw new IllegalArgumentException();

       
}

       
x += dx;

       
y += dy;

    }

   
//Copy otherCircle into this circle

   
public void copy(Circle otherCircle)
{

       
x = otherCircle.x;

       
y = otherCircle.y;

       
radius = otherCircle.radius;

    }

   
//Make a copy of this circle

   
public Circle getCopy() {

       
Circle cop =  new Circle(x, y, radius);

       
return cop;

    }

}

//Rectangle
Class, implementing Figure

public class Rectangle
implements Figure {

   
private double length;

   
private double width;

   
//default constructor

   
public Rectangle()  {

       
length = 0;

       
width = 0;

    }

   
//alternate constructor

   
public Rectangle(double l, double w) {

       
length = (l >= 0)? l: 0;

       
width = (w >= 0)? w: 0;

       
//set(l, w);

    }

    public void set(double l, double w)  {
       
length = (l >= 0)? l: 0;

       
width = (w >= 0)? w: 0;

    }

    public double getLength() {

       
return length;

    }

    public double getWidth() {
       
return width;

    }

    public double getArea() {
       
return length * width;

    }

    public double getPerimeter() {

       
return 2 * (length + width);

    }

   
// Returns the number of sides a rectangle has (4).

    public int getSideCount()
{

       
return 4;

    }

    public void print() {
       
System.out.print(“Length = ”  + length
+ “; Width = ” + width);

    }

    public String toString() {
       
return “Length = ”  + length + “; Width = ” + width;


    }

    public boolean equals(Object obj) {
       
if (obj instanceof
Rectangle) {

           
Rectangle otherRectangle = (Rectangle) obj;

           
return length == otherRectangle.length &&
width == otherRectangle.width;

       
}

       
else   // not a Rectangle object


           
return false;

    }

}

//Triangle
Class, implementing Figure.

public class Triangle implements
Figure {

   
private double a;

   
private double b;

   
private double c;

    public Triangle() {
       
a = 0;

       
b = 0;

       
c = 0;

    }

   
// Constructs a new Triangle given side lengths.

    public Triangle(double a, double b, double c) {
       
this.a = a;

       
this.b = b;

       
this.c = c;

    }

   
// Returns this triangle’s area using Heron’s formula.

    public double getArea() {
       
double s = (a + b + c) / 2.0;

       
return Math.sqrt(s * (s – a) * (s – b) * (s – c));


    }

   
// Returns the perimeter of this triangle.

    public double getPerimeter() {

       
return a + b + c;

    }

   
// Returns the number of sides a triangle has (3).

    public int getSideCount()
{

       
return 3;

    }

    public void print() {
       
System.out.print(“side a = ”  + a +
“; side b = ” + b + “; side c = ” + c);

    }

    public String toString() {
       
return “side a = ”  + a + “; side b = ” + b + “;
side c = ” + c;

    }

    public boolean equals(Object obj) {
     
if (obj instanceof
Triangle) {

         
Triangle otherTriangle = (Triangle) obj;

         
return a == otherTriangle.a && b == otherTriangle.b  && c == otherTriangle.c;


     
}

     
else   // not a Triangle object


         
return false;

    }

}

//
Client for classes implementing Figure.

public class ClientFigures {
   
public static final int MAX = 3;

   
public static void main(String[] args) {

       
Figure[] fig = new Figure[MAX];

       
fig[0] = new Rectangle(37, 20);

       
fig[1] = new Triangle(37, 20, 30);

       
fig[2] = new Circle(0, 0, 37);

       
int sides;

       
for (int i = 0; i < fig.length; i++) {

           
sides = fig[i].getSideCount();


           
switch(sides) {

               
case 0:

                   
System.out.print(“nThis
is a circle. “);

                   
break;

               
case 3:

                   
System.out.print(“nThis
is a triangle. “);

                   
break;

               
case 4:

                   
System.out.print(“nThis
is a rectangle. “);

           
}

           
System.out.printf(“Area = %.2f”, fig[i].getArea());

           
System.out.printf(“. Perimeter = %.2fn”,
fig[i].getPerimeter());

           
System.out.println(“Output calling the method printInfo – polymorphism at work!”);

           
printInfo(fig[i]);

       
}

    }

   
//Any object that implements the interface may be passed as parameter to this
method.

    public static void printInfo(Figure
f) {

       
System.out.println(“For this figure: ” +
f);

       
System.out.printf(“Area = %.2f”, f.getArea());

       
System.out.printf(“; Perimeter = %.2fn”, f.getPerimeter());

    }

}
OUTPUT:

This is a rectangle.
Area = 740.00. Perimeter = 114.00

Output calling the
method printInfo – polymorphism at work!

For this figure:
Length = 37.0; Width = 20.0

Area = 740.00;
Perimeter = 114.00

This is a triangle.
Area = 299.50. Perimeter = 87.00

Output calling the
method printInfo – polymorphism at work!

For this figure: side
a = 37.0; side b = 20.0; side c = 30.0

Area = 299.50;
Perimeter = 87.00

This is a circle.
Area = 4300.84. Perimeter = 232.48

Output calling the
method printInfo – polymorphism at work!

For this figure:
center at (0, 0), radius = 37.0

Area = 4300.84;
Perimeter = 232.48

Composition:
Classes: Person, Date, PersonalInfo

//Class
Person:

public class Person {

   
private String firstName;

   
private String lastName;

    //Default constructor
   
public Person() {

       
firstName = ” “;

       
lastName = ” “;

    }

    //Alternate Constructor
   
public Person(String first, String last) {

       
setName(first, last);

    }

    //Copy constructor
   
public Person(Person original) {

       
if(original == null)  {

           
System.out.println(“Fatal error for this
Person.”);

           
System.exit(0);

       
}

       
firstName = original.firstName;


       
lastName = original.lastName;


    }

    public String toString(){
       
return (lastName + “, ” + firstName);

    }

    public void printLastFirst() {

       
System.out.print(lastName +
“, ” + firstName);

    }

    public void printFirstLast() {

       
System.out.print(firstName
+ ” ” + lastName);

    }

    public void setName(String first,
String last) {

       
firstName = first;

       
lastName = last;

    }

    public String getFirstName() {

       
return firstName;

    }

    public String getLastName() {

       
return lastName;

    }

    public boolean equals(Object obj) {
     
if (obj instanceof Person)
{

         
Person otherPerson = (Person) obj;


         
return lastName.equals(otherPerson.lastName)
&& firstName.equals(otherPerson.firstName);


     
}

     
else   // not a Person object

         
return false;

    }

}

//Class
Date:

public class Date {

   
private int month;

   
private int day;

   
private int year;

   
//Default constructor

   
public Date() {

       
month = 0;

       
day = 0;

       
year = 1900;

    }

   
//Alternate constructor

   
public Date(int m, int d, int y) {

       
month = (m >=1 && m <= 12)? m: 0;

       
day = (d >=1 && d <= 31)? d: 0;

       
year = (y >=1900 && y <= 2020)? y: 0;

       
//setDate(m, d, y);

    }

   
//Copy constructor

   
public Date(Date original) {

       
if(original == null)  {

           
System.out.println(“Fatal error for this
Date.”);

           
System.exit(0);

       
}

       
month = original.month;

       
day = original.day;

       
year = original.year;

    }

    public void setDate(int m, int d, int
y) {

       
month = (m >=1 && m <= 12)? m: 0;

       
day = (d >=1 && d <= 31)? d: 0;

       
year = (y >=1900 && y <= 2020)? y: 0;

    }

    public int getMonth()
{

       
return month;

    }

    public int getDay()
{

       
return day;

    }

    public int getYear()
{

       
return year;

    }

    public String toString() {
       
return (month + “-” + day + “-” + year);

    }

    public boolean equals(Object obj) {
     
if (obj instanceof Date) {


         
Date otherDate = (Date) obj;


         
return month == otherDate.month && day == otherDate.day && year == otherDate.year;


     
}

     
else   // not a Date object

         
return false;

    }

}

//Class
PersonalInfo (composition)

public class PersonalInfo {
   
private Person fullName; //(class) Person type

   
private Date birthDate//(class) Date type

    private
int personID;

   
//Default constructor

   
public PersonalInfo() {

       
fullName = new Person();

       
birthDate = new Date();

       
personID = 0;

    }

   
//Alternate constructor

   
public PersonalInfo(String first, String last, int m,
int d, int y, int id) {

       
fullName = new Person(first, last);

       
birthDate = new Date(m, d, y);

       
personID = id;

    }

   
//Copy constructor

   
public PersonalInfo(PersonalInfo original) {

       
if(original == null)  {

           
System.out.println(“Fatal error.”);

           
System.exit(0);

       
}

       
//Person has to have a copy constructor!

       
fullName = new Person(original.fullName);


       
//Date has to have a copy constructor!

       
birthDate = new Date(original.birthDate);


       
personID = original.personID;


    }

    public void setPersonalInfo(String
first, String last, int m, int
d, int y, int id) {

       
fullName.setName(first, last); //method setName in class
Person

       
birthDate.setDate(m, d, y);    //method setDate in class Date


       
personID = id;

    }

    public Person getfullName( ){

       
return new Person(fullName); //Person
has to have a copy constructor!

    }

    public Date getBirthDate( ){

       
return new Date(birthDate); //Date
has to have a copy constructor!

    }

    public int getPersonID(
){

       
return personID;

    }

    public String toString() {
    //return (“Name: ” + fullName.toString()
+ “nDate of birth: ” + birthDate.toString()
+ “nPersonal ID: ” + personID);


      
//Same as:

      
return (“Name: ” + fullName + “nDate of birth: ” + birthDate
+ “nPersonal ID: ” + personID);


    }

   
public boolean equals(Object obj)
{

       
if (obj instanceof PersonalInfo) {

           
PersonalInfo otherPerson =
(PersonalInfo) obj;

           
return  fullName.equals(otherPerson.fullName)
&& birthDate.equals(otherPerson.birthDate)
&& personID == otherPerson.personID;


       
}

       
else   // not a PersonalInfo object

           
return false;

    }

    
/*Another version for equals:

   
public boolean equals(PersonalInfo
otherPerson) {

       
if (otherPerson == null)

           
return false;

       
else

           
return  fullName.equals(otherPerson.fullName)
&& birthDate.equals(otherPerson.birthDate)
&& personID == otherPerson.personID;


   
}*/

    public boolean sameName(Object
obj) {

       
if (obj instanceof PersonalInfo) {

           
PersonalInfo otherPerson =
(PersonalInfo) obj;

           
return  fullName.equals(otherPerson.fullName);//equals from Person

       
}

       
else   // not a PersonalInfo object

         
return false;

    }

    public boolean sameBirthDate(Object
obj) {

       
if (obj instanceof PersonalInfo) {

           
PersonalInfo otherPerson =
(PersonalInfo) obj;

           
return  birthDate.equals(otherPerson.birthDate);//equals from Date

       
}

       
else   // not a PersonalInfo object

         
return false;

    }

    public boolean sameID(Object
obj) {

       
if (obj instanceof PersonalInfo) {

           
PersonalInfo otherPerson =
(PersonalInfo) obj;

           
return  personID == otherPerson.personID;


       
}

       
else   // not a PersonalInfo object

         
return false;

    }

}

//Client
for PersonalInfo class

public class ClientComposition {
   
public static void main(String[] arg)   {


       
PersonalInfo newStudent =
new PersonalInfo(“James”,
“Smith”, 2, 20, 1988, 12345678);

       
System.out.println(newStudent);


       
PersonalInfo otherStudent =
new PersonalInfo(“Jim”, “Smith”,
2, 20, 1988, 12345679);

        
System.out.println(otherStudent);


       
if(newStudent.equals(otherStudent))


           
System.out.println(“Same personal info.”);


       
else

           
System.out.println(“NOT same personal
info.”);

       
if(newStudent.sameName(otherStudent))


           
System.out.println(“Same name for both
students.”);

       
else

           
System.out.println(“Students don’t have the same
name.”);

       
if(newStudent.sameBirthDate(otherStudent))


           
System.out.println(“Same birthdate for both
students.”);

       
else

           
System.out.println(“Students don’t have the same
birthdate.”);

       
if(newStudent.sameID(otherStudent))


           
System.out.println(“Something is wrong! Same ID
for both students.”);

       
else

           
System.out.println(“Students don’t have the same ID.”);

    }

}
OUTPUT:

Name: Smith, James

Date of birth:
2-20-1988

Personal ID: 12345678

Name: Smith, Jim

Date of birth:
2-20-1988

Personal ID: 12345679

NOT same personal
info.

Students don’t have
the same name.

Same birthdate for
both students.

Students don’t have
the same ID.

Key Terms

Abstract class:  A class that is declared with the reserved word
abstract.  You cannot
instantiate an object of an abstract class.
Abstract method: A method that has
only the heading with no body.
Composition: The use of classes as
instance variables in the definition of another class.
Dynamic binding: The method that gets executed is determined at
execution time not compile time; same as run-time binding.
Interface: A class that contains only
abstract methods and/or named constants. This is how Java implements multiple
inheritance, which is not true multiple inheritance.
Overriding: Declaring a method in a
subclass with the same signature as a method in its superclass.
Overloading: Declaring a method with
the same name, different parameters.
Polymorphism: Assigning multiple
meanings to the same method name. The ability for the same code to be used with
several different types of objects and behave differently depending on the type
of object used.
Run-time binding: The method that
gets executed is determined at execution time not compile time; same as dynamic
binding
.

Additional
Resources:

1. (Sun) API specification for version 6 of the Java™ Platform, Standard
Edition (Class Object): http://java.sun.com/javase/6/docs/api/

2. (Sun) The Java Tutorials, Interfaces: http://java.sun.com/docs/books/tutorial/java/IandI/createinterface.html

References:
[1] Java Programming: From Problem Analysis to Program Design, by D.S. Malik,
Thomson Course Technology, 2008
[2] Building Java Programs
: A Back to Basics Approach, by Stuart Reges, and Marty Stepp, Addison
Wesley, 2008.
 


View more information: http://orion.towson.edu/~izimand/237/LectureNotes/3-Lecture-Polymorphism.htm

See more articles in category: Grammar
READ:  Champagne Taste on a Beer Budget

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button