Download Manual - MSCS - Marquette University

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
J A V A
L A B
M A N U A L
LAB
OBJECT ORIENTED PROGRAMMING IN JAVA
13
Inheritance & Polymorphism
PURPOSE
The use of inheritance to promote code reuse and
TO PREPARE FOR THIS
LAB

Read Wu: Chapter 13 pages

Read through this laboratory session

Using your memory device, create a directory called lab13 and copy the four file
http://www.mscs.mu.edu/~marian/Labs/lab13/Pets1.java .
TO COMPLETE THIS LAB

This is an individual lab. You may ask the lab tutor for help and you may consult with your
neighbor if you are having difficulties.

In this lab, you will complete Pets1.java and create two new files, Pets2.java and Pets3.java

When you have completed the lab, hand in copies of all three files, each of which contains the
results of one run of the program.
M. MANYO, MARQUETTE UNIVERSITY
PAGE 13.1
13.1 FUNDAMENTALS OF INHERITANCE - PART 1
P r o g r a m : Open Pets1.java
Object-oriented programming languages such as Java provide a mechanism, called i nhe ri tan ce , to
describe new classes in terms of existing ones The original class is called the base class, and a class that is
built using the base class is called the derived class. Other terminology for the base class is parent class or
super class. And, related terminology for the derived class is child class or sub class.
As an example, let's create classes such as Dog, Snake, and Poodle that can be used to keep track of
information about a collection of pets. Since each pet has a name, each of these classes should have a data
member String name and a getName method. This redundancy can be avoided by first defining a base
class Pet from which the other classes are derived. The Pet class should define the data and methods that
are common to all Pet objects. The non-private class members will be inherited by any class derived from
the Pet class. The protected access modifier indicates that a class member is private to an outside class
but is inherited by a sub class. Therefore, any class derived from the Pet class will inherit the instance
variable protected String name and the method public String getName().
class Pet
{
protected String name;
public Pet()
{
name = "Unknown";
}
public Pet(String n)
{
name = n;
}
public String getName()
{
return name;
}
}
The inheritance relationship in Java is indicated by the reserved word extends. Therefore,
class Dog extends Pet
indicates that Pet is the base, or super, class and Dog is the derived, or sub, class.
class Dog extends Pet
{
public Dog(String s)
{
name = s;
}
}
Since a constructor must have a name that matches the class name, constructors are not inherited by the
sub class. However, any constructor of a sub class must call, either implicitly or explicitly, a constructor of
the super class. If the call to the constructor of the super class is implicit, the super class must have a
constructor with no parameters, such as public Pet(). If the call to the constructor of the super class is
explicit, the call must be the first statement in the body of the constructor of the sub class. The initial
version of the Dog class contains the single constructor public Dog(String s), which contains a single
PAGE 13.2
M. MANYO, MARQUETTE UNIVERSITY
J A V A
L A B
M A N U A L
statement that initializes the inherited instance variable name. Because it is implied, the call to Pet()
does not appear.
S t e p 1 : The Pet and Dog classes are defined in the program file Pets1.java along with the driver class
Pets1. Predict the output of the program.
class Pets1
{
public static void main(String[] args)
{
Pet aPet = new Pet("George");
Dog aDog = new Dog("Spot");
System.out.println(aPet.getName());
System.out.println(aDog.getName());
}
}
___________________________________________________________________________________________
___________________________________________________________________________________________
Compile and execute the program Pets1.java. Correct you predicition if needed.
S t e p 2 : Comment out the entire constructor public Pet() in class Pet . Record the compiler error
message.
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
As previously stated, if the constructor in the sub class does not explicitly call a constructor from the super
class, it will implicitly call the super class constructor with no parameters. When this constructor is
omitted, the Dog class does not compile. To correct, uncomment the constructor. It is generally a good idea
to include a default constructor in all of your utility classes to avoid this problem.
The constructor in the Dog class can explicitly call the constructor in the Pet class that initializes the
instance variable name. The sub class always refers to its super class with the name super .
S t e p 3 : Modify the constructor in the Dog class to explicitly call the constructor
public Pet(String n)in the super class. Replace
name = s;
with
super(s);
When s is passed to super, the constructor public Pet(String n) is called and s is assigned to n, which
is then assigned to name . Compile and execute the revised program. Record the results.
___________________________________________________________________________________________
___________________________________________________________________________________________
S t e p 4 : Now, let's add more methods to the Pet class. These will be methods that describe behaviors
common to all classes that will be derived from Pet . Since all pets can move and speak, we will add move()
and speak() methods to the Pet class. Also, all classes should have a toString () . Add these methods to
the Pet class:
M. MANYO, MARQUETTE UNIVERSITY
PAGE 13.3
public String move()
{
return "run";
}
returns the String "run" since many pets, but not all, can run.
public String speak()
{
return "";
}
returns the empty String "" since there is no generic way for a pet to speak.
public String toString()
{
return "My pet " + name;
}
Compile the file.
S t e p 5 : Now make changes to the Dog class. A sub class may define additional data members, which are
unknown in the super class. In the class Dog , define an instance variable
protected int weight;
that is modified by protected so that subclasses of Dog will inherit weight. Now, modify the Dog
constructor to have a second parameter that initializes weight .
Compile the file.
S t e p 6 : There are four ways to define methods in a sub class.
1. Define methods in the sub class with no connection to the super class.
A. Add an accessor method that returns the weight
2. Overwrite the inherited method.
B. Overwrite the speak method to return "Woof Woof"
3. Overwrite the inherited method, but call the inherited method
C. Overwrite the inherited toString method, but call the super class toString method. To do this use
the statement:
return super.toString() + " is a dog and weighs "+ weight + " pounds";
4. Inherit a method as is.
D. Do not modify the move method.
Now uncomment the code in the main method that tests the modified classes.
Pet myPet = new Pet("George");
Dog myDog = new Dog("Spot", 15);
System.out.println(
"\n" + myPet.toString() +
"\n
" + "Speak: " + myPet.speak() +
"\n
" + myPet.move() + " " + myPet.getName() + " " + myPet.move());
System.out.println(
"\n" + myDog.toString() +
"\n
Speak: " + myDog.speak() +
"\n
Weighs: " + myDog.getWeight() + " pounds" +
"\n
" + myDog.move() + " " + myDog.getName() + myDog.move() + "\n");
PAGE 13.4
M. MANYO, MARQUETTE UNIVERSITY
J A V A
L A B
M A N U A L
Compile the file Pets1.java and run the program. Record the results.
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
S t e p 7 : Add another class, Snake, to the file Pets1.java that satisfies the following requirements.
o
o
o
o
The class Snake is a sub class of the class Pet
Snake has an additional instance variable int length
Constructor: public Snake(String s, int len) initializes the name and length
Methods:
o public int getLength()
o public String speak() returns "Hiss Hiss"
o public String move() returns "slither"
o public String toString() returns "My pet __ is a snake and is __ inches long"
Then , add statements to the main method that create a Snake object and test its methods. Record any
difficulties.
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
S t e p 8 : Add another class, Poodle, to the file Pets1.java that satisfies the following requirements.
o
o
o
The class Poodle is a sub class of the class Dog
Constructor: public Poodle(String n, int w) initializes the name and weight
Methods:
o public String speak() returns "Yip Yip"
o public String toString() returns "My pet __ is a poodle and weighs __ pounds"
Then , add statements to the main method that create a Poodle object and test its methods. Record any
difficulties.
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
M. MANYO, MARQUETTE UNIVERSITY
PAGE 13.5
S t e p 9 : Answer these questions about the Poodle class.
1. Which class is the super class of Poodle ? ____________________________________________
2. List all the methods that are inherited by the Poodle class. Also, identify the class in
which each method is defined.
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
13.2 POLYMORPHISM AND INHERITANCE
The inheritance relationship is called the "is a" relationship because we can say that "A Dog is a Pet", "A
Snake is a Pet", "A Poodle is a Dog" and, we can also say "A Poodle is a Pet". The class hierarchy that has
been defined can be illustrated using the diagram
Pet
|
|
Dog
|
Poodle
|
Snake
The word po lymo rph i sm means "many forms" and has two applications in object-oriented languages.
The first, which we have already seen, are polymorphic methods, known as overloaded methods. The
second is polymorphic references, which are reference that may refer to many forms (types) of objects. For
example, the Pet reference myPet may refer to a Pet, Dog, Snake or Poodle object since each of these is a
Pet . Therefore, an array of type Pet[] is used to store Pet references that can refer to a Pet object or to any
object whose class is derived from the class Pet.
S t e p 1 0 : Comment out the previously executed statements in main and uncomment the following
statements.
Pet[] myPets = new Pet[4];
myPets[0] = new Pet("George");
myPets[1] = new Dog("Spot", 50);
myPets[2] = new Poodle("Rocky", 16);
myPets[3] = new Snake("Bruno", 20);
for(int j = 0; j < myPets.length; j++)
{
System.out.println(myPets[j].toString());
}
Predict what will be printed. Compile and execute the program. If needed, correct your predictions.
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
PAGE 13.6
M. MANYO, MARQUETTE UNIVERSITY
J A V A
L A B
M A N U A L
The principle of polymorphism guarantees that the toString method that is executed depends on the
data type of the object, not on the data type of the reference ( Pet ). When
System.out.println(myPets[1].toString())
is executed, the toString method that is invoked is from the Dog class. When
System.out.println(myPets[3].toString())
is executed, the toString method that is invoked is from the Snake class.
S t e p 1 1 : Modify the main method by adding thisfollowing code to the body of the for loop.
System.out.println("Speak: " + myPets[j].speak());
System.out.println(myPets[j].move() + " " + myPets[j].getName() + "\n");
Mentally predict what will be printed. Compile and execute the program. Record any comments.
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
S t e p 1 2 : Modify the main method by adding the following code to the body of the for loop.
System.out.println("
Weight: " + myPets[j].getWeight());
Predict the error. Compile the program. Record and explain the error message.
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
S t e p 1 3 : The Java operator instanceof determines whether its first operand, an Object, is an instance
of its second operand, a data type. The expression
myPets[j] instanceof Dog
has a value of true or false .
Modify the for loop of the main method by replacing the statement added in Step 12 with
if(myPets[j] instanceof Dog)
System.out.println("
Weight: " + myPets[j].getWeight());
Compile the code and record the error message.
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
The getWeight method is defined in the Dog class. Since the Pet class does not define a getWeight
method that compiler finds an error. Therefore, even though the print statement is executed only if
myPets[j] references a Dog object, the Pet reference myPets[j] must be cast to a Dog reference .
M. MANYO, MARQUETTE UNIVERSITY
PAGE 13.7
Change the print statement to
System.out.println("
Weight: " + (Dog)myPets[j].getWeight());
Compile the code and record the error message.
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
The dot operator . has higher precedence that a cast (type) . Therefore, another set of parentheses is
needed. Make this modification.
System.out.println("
Weight: " + ((Dog)myPets[j]).getWeight());
Mentally predict what will be printed. Compile and execute the program. Record any comments
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
Answer this question: What is the value of myPets[2] instanceof Dog ? Explain.
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
The Object class
In Java, all classes that do not explicitly extend a class, implicitly extend the class Object that is defined
in the java.lang package. Therefore, every class is a descendant of the Object class. Specifically, the
definition of the Pet class which begins with
class Pet
implicitly states that the super class of Pet is the Object class. Stating this explicitly, the definition of the
Pet class would begin with
class Pet extends Object
Among the methods that are inherited by all classes from Object are two methods that we have worked
with, toString and equals. The equals method defined in the class Object returns true if the
reference passed to the method == this reference. This method should be overwritten to compare the state
of the two objects whenever possible. The toString method returns a string representation of the object
and is automatically invoked on an object whenever a string representation is needed. For example, in
order to print an object, a String is needed. This is why these two statements produce the same output.
System.out.println(myPets[j].toString());
System.out.println(myPets[j]);
PAGE 13.8
M. MANYO, MARQUETTE UNIVERSITY
J A V A
L A B
M A N U A L
Add this code that uses the inherited equals method to the main method after and outside of the for loop.
Pet p = new Pet("George");
if (p.equals(myPets[0]))
System.out.println("Same pet");
else
System.out.println("Different pets");
p = myPets[0];
if (p.equals(myPets[0]))
System.out.println("Same pet");
else
System.out.println("Different pets");
Compile and execute the program. Explain the results.
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
___________________________________________________________________________________________
Abstract classes and Interfaces
Two other approaches to defining the Pet hierarchy of classes are to make the Pet class an abstract class
or to make Pet an interface.
P r o g r a m : Save your file Pets1.java as Pets2.java
Make the following initial changes:
 Change the name of the class : class Pets1 to class Pets2
 You may "clean up" the main method. Keep only the portion that declares and fills the array and
the associated for loop.
An a b str ac t me thod is a method that has no body. To define an abstract method, use the Java reserved
work abstract, followed by the method header, followed by a semi-colon. For example, the speak method
of the Pet class could be written as an abstract method rather than a method that returns an empty
String. An a b str ac t c la ss is a class that contains at least one abstract method and must be declared to
be abstract. Objects cannot be created from an abstract class. Any class that extends an abstract class
must define bodies for all abstract methods, or the sub class must also be declared to be abstract.
S t e p 1 : Make the following modifications to the Pet class. Replace the entire speak method with the
single statement that is the abstract method header
abstract public String speak();
And, declare the Pet class to be abstract by adding abstract to the class declaration
abstract class Pet
Compile the modified program and record the error message. Explain
____________________________________________________________________________________
____________________________________________________________________________________
M. MANYO, MARQUETTE UNIVERSITY
PAGE 13.9
S t e p 2 : Modify the driver class by replacing the statement
myPets[0] = new Pet("George");
with the statement
myPets[0] = new Dog("George", 100);
Compile and execute the modified program. Record the results.
____________________________________________________________________________________
____________________________________________________________________________________
____________________________________________________________________________________
____________________________________________________________________________________
____________________________________________________________________________________
P r o g r a m : Save your file Pets2.java as Pets3.java
Change the name of the class : class Pets2 to class Pets3
S t e p 3 : An i n terf ace can only define constant data members and abstract methods, which do not need
the modifier abstract since they are abstract by default. Interfaces are not extended, rather they are
implemented. Replace the entire Pet class with the Pet interface.
interface
{
public
public
public
}
Pet
String move();
String speak();
String toString();
The Pet interface cannot define the instance variable name and, therefore, should not list getName as a
method in the interface.
S t e p 4 : Make these changes to the Dog class.
1. Since Pet is no longer a class but, is an interface change the class header to
class Dog implements Pet
The super class of Dog is now implicitly the class Object .
2. Define the instance variable name, which will be inherited by any classes derived from
Dog (Poodle) . Also, define a getName method.
3. Define the move method
4. Modify the toString method since the super class is now Object .
S t e p 5 : Where needed, make similar changes to the Snake class. Record the changes that you need to
make.
____________________________________________________________________________________
____________________________________________________________________________________
____________________________________________________________________________________
PAGE 13.10
M. MANYO, MARQUETTE UNIVERSITY
J A V A
L A B
M A N U A L
____________________________________________________________________________________
____________________________________________________________________________________
S t e p 6 : The interface Pet may be used as a data type. Therefore, the array of type Pet[] is still valid
and may store references to objects of any class that implements the Pet interface or is derived from a
class that implements the Pet interface.
Compile and execute the program. Record any problems that you had.
____________________________________________________________________________________
____________________________________________________________________________________
____________________________________________________________________________________
____________________________________________________________________________________
____________________________________________________________________________________
____________________________________________________________________________________
____________________________________________________________________________________
____________________________________________________________________________________
S t e p 7 : Explain why it was not necessary to make any changes to the class Poodle .
____________________________________________________________________________________
____________________________________________________________________________________
____________________________________________________________________________________
____________________________________________________________________________________
____________________________________________________________________________________
M. MANYO, MARQUETTE UNIVERSITY
PAGE 13.11