Download Notes

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
Week 3: Object-Oriented Programming - Inheritance
(Read Ch.13 in Horstmann, Ch.7 in Lewis&Loftus 2nd ed., Ch.9 in Deitel&Deitel 3rd ed.)
Code reuse is important in software engineering and inheritance is one way to do it.
- Inheritance allows to define a class that is similar to an existing class
- it just adds a few new attributes or methods, or implements existing methods
differently
- OOP supports declaring the new class as a subclass, which extends the old class
- the subclass inherits all the attributes and methods of the original class
- it can add new ones, as well as override the implementation of existing methods
Example: A hierarchy of related classes: The class Undergrad is a subclass (or
specialization) of Student. Inversely, we say that Student is a superclass (or
generalization) of Undergrad.
class Student {
// instance attributes
private String name;
private long number;
//constructor
public Student(String aName, long aNumber){
name = aName;
number = aNumber;
}
// instance methods
public void setName(String aName){
name = aName;
}
public String getName(){
return name;
}
public void setNumber(long aNumber){
number = aNumber;
}
public long getNumber(){
return number;
}
public String toString(){
return "Student[name=" + name + ",number=" + number + "]";
}
}
class Undergrad extends Student{
// instance attributes ( name and number are inherited from Student)
private String major;
private int year;
// instance methods setName, getName, setNumber, & getNumbers are inherited
from Student
//constructor
public Undergrad(String aName, long aNumber, String aMajor, int aYear){
super (aName, aNumber);
setMajor (aMajor);
setYear(aYear);
}
// new methods
public void setMajor(String aMajor){
major = aMajor;
}
public String getMajor(){
return major;
}
public void setYear(int aYear){
year = aYear;
}
public int getYear(){
return year;
}
// overriding the base class toString()
// note that private base class attributes are not available in the subclass
public String toString(){
return "Undergrad[name=" + getName() + ",number=" + getNumber() + "
,major=" + major +
",year=" + year + "]";
}
}
public class Inh1 {
public static void main(String[] args){
Student s1 = new Student("John",202123456);
System.out.println("s1 is " + s1.getName());
System.out.println(s1.toString());
Undergrad s2 = new Undergrad("Mary",201234567,"ITEC",1);
System.out.println("s2 is "+s2.getName());
//inherited
s2.setName("Mary Ellen");
//inherited
System.out.println("s2 is in year " + s2.getYear()); //new method
System.out.println(s2.toString());
}
}
Note: Every instance of a class is also an instance of all it superclasses (similar to sets).
So an instance of Undergrad is also an instance of Student (ie s2 is also a Student object).
Note: Another implementation of the subclass method toString(), which uses the base
class toString():
public String toString(){
// call superclass’s method
String s = super.toString();
// make appropriate changes & return
s = s.substring(s.indexOf("["),s.length()-1);
return "Undergrad" + s + ",major=" + major + ",year=" + year + "]";
}
Inheritance class architecture
Student
Undergrad
Postgrad
Other examples of “is a” type
relationship:
BankAccount
Person
Employee
CheckingAccount
SavingsAccount
Programmer
Sometimes inheritance means just expanding information and the “is a” meaning is not
suitable. Ex. Point <- Circle <- Cylinder.
Overloaded vs Overridden Methods
It is important to distinguish between overloaded and overridden methods.
Overloading
-
you are defining several methods with the same name that will be available in the
same class.
this is only possible when the signatures of the methods are different.
Overwriting
-
overridden methods have the same signature.
the method in the subclass replaces that in the superclass
the superclass’s version is still available using super
public class Parent {
public void meth() // #1
{ ...
}
public void meth(int n) // #2, overloads #1
{ ...
}
...
}
public class Offspring extends Parent {
public void meth(int n) // #3, overrides #2
{ ...
}
...
}
...
// in main
Parent o1 = new Parent();
Offspring o2 = new Offspring();
o1.meth(); // calls #1
o1.meth(31); // calls #2
o2.meth(); // calls #1
o2.meth(29); // calls #3
Inheritance and Attributes
-
-
attributes defined in a super-class are inherited by the subclass, but are not
directly accessible (assuming they are private)
they can only be accessed through inherited public methods
if you redefine an attribute in the subclass, the new attribute does not replace the
original one, as they are stored in different memory areas
the subclass attribute will shadow the one defined in the superclass
the use of protected instead of private for the superclass attributes allows the
derived classes to directly access those attributes (no need to use methods to
access them).
if the superclass’s attribute is protected, and there is another derived class
attribute with the same name (bad idea !), you can refer to the base class attribute
as super.attribute.
public class Parent{
...
public setAtt(int n){
att = n;
}
private int att;
}
public class Offspring extends Parent{
public void meth(){
att = 4;
// sets Offspring’s att
setAtt(3);// sets Parent’s att
}
private int att;
}
// in main
Offspring o = new Offspring();
o.meth();
Constructors and Inheritance
-
an instance of a class C in a hierarchy is also an instance of all of C’s superclasses
(all the way to the top).
Therefore when you call the constructor of C you have to call the constructors of
all of C’s superclasses
You can call a constructor of C’s superclass by putting super(...) in C’s
constructor
If you leave out the call to the superclass’s constructor, Java automatically inserts
super() at the beginning of the subclass’s constructor, i.e. a call to the superclass’s 0 arguments constructor, that initializes the attributes to default values, 0
for numbers, false for boolean, and null for objects.
public class Student{
public Student() {
name = "UNKNOWN";
number = -1;
}
public Student(String aName, long aNumber){
name = aName;
number = aNumber;
} ...
private String name;
private long number;
}
public class Undergrad extends Student{
public Undergrad(){
super();// calls Student’s 0 args constructor
major = "general";
year = 1;
}
public Undergrad(String aName, long aNumber, String aMajor, int aYear){
super(aName, aNumber);// calls Student’s 2 args constructor
major = aMajor;
year = aYear;
} ...
private String major;
private int year;
}
// in main
Undergrad u = new Undergrad("John", 201234567, "ITEC", 1);
If there are more than one constructor, each ancestor class’s constructor is called in turn.
Ex.:
public class PartTimeUndergrad extends Undergrad{
//constructors
public PartTimeUndergrad(){
super();// calls Undergrad’s 0 args constructor
courseLoad = 2.5;
}
public PartTimeUndergrad(String aName, long aNumber, String aMajor, int aYear, double aLoad)
{
super(aName, aNumber, aMajor, aYear); // calls Undergrad’s 4 args constructor
courseLoad = aLoad;
}
...
private double courseLoad;
}
// in main
PartTimeUndergrad p = new PartTimeUndergrad("John", 201234567, "ITEC", 1, 3.5);
Ex.2.5
Define a method public double calculateFees(double courseload) for Student and
Undergrad which returns the fees to be paid by the student depending on his/her
courseload. Suppose that for students generally, the fees are $800 per course and that for
undergraduates, there is an additional incidental charge of $100 for first year students
and $150 for students in later years.
public class Student{
...
public double calculateFees(double courseload){
final double FEE_PER_COURSE = 800;
return FEE_PER_COURSE * courseload;
}
...
}
public class Undergrad extends Student{
...
// override Student’s calculateFees method
public double calculateFees(double courseload){
final double INCIDENTAL_FEE_Y1 = 100;
final double INCIDENTAL_FEE_Y_GT_1 = 150;
double fee = super.calculateFees(courseload);
if (year == 1)
fee = fee + INCIDENTAL_FEE_Y1;
else
fee = fee + INCIDENTAL_FEE_Y_GT_1;
return fee;
}
...
}
// in main
Student s = new Student("Mary", 202345678);
York.println(s + " fees: " + s.calculateFees(4.5));
Undergrad u = new Undergrad("John", 201234567, "ITEC", 1);
York.println(u + " fees: " + u.calculateFees(4.5));
Student s1=u;
// this will not COPY an object; it will just create another reference to the same object
An Undergrad object “is a” Student object too. This why s1 can point to the object u;
however s1 will see only the Student part of u. You cannot do the same thing between
unrelated classes.
The Cosmic Superclass
- All classes in Java ultimately inherit from the Object class.
- All new classes are part of Sun’s object hierarchy.
- The Object class contains the following methods: String toString(), equals(Object
obj), Object clone()
- You can use the Object methods or, better, overwrite them in your classes
The following code can be used with any object s:
s1=s.clone();
if (s1.equals(s))
York.println(“The two objects are identical”);
Final Methods
-
In writing classes one has to keep in mind that future applications might be
extending them through inheritance.
In this sense one has to think on whether to declare base class variables protected
instead of private.
As far as the methods are concerned base class methods can be overridden by
derived class methods (having the same signature).
-
Occasionally a base class method MUST be used always with the same code and
programmers can enforce it by using the modifier final in front of that base class
method declaration.
Abstract Classes
-
An abstract class represents a generic concept in the class hierarchy.
It cannot be instantiated and it might contain one or more abstract methods, which
have no definition.
Both class and abstract methods declarations must have the abstract modifier in
front.
Note that a static or final method cannot be also abstract.
Ex. Vehicle can be made an abstract class as it is too generic for applications. Car, Boat
and Plane can be derived from Vehicle. Vehicle might contain just the variable speed and
the method fuelConsumption() could be abstract, with implementations only in the
derived classes. More about abstract classes when we discuss interfaces.
Graphics
(Read ch.4 in Horstmann, ch.9 in Lewis & Loftus and ch.11 in Deitel&Deitel)







Using JOptionPane methods gave you a first glimpse at what Java has to offer in
terms of user interface. The JOptionPane boxes were created on top of the black
screen. Automatically they provided an “OK” button which closed them.
Later we shall discuss much more Graphics User Interface (GUI) techniques.
Most of the GUI classes are provided in Java by the Abstract Windowing Tools
(AWT) package (java.awt).
With the arrival of the Java 2 platform AWT was expanded with the Swing
classes (java.swing). Swing classes provide alternative components that have
more functionality than AWT and therefore we shall prefer to use Swing.
With graphics one can easily draw shapes, one can control colors and fonts, one
can organize the screen in a user-friendly way.
One of Java’s initial appeals was its support for GUI. Unlike in other OOP
languages (such as C++), building an appealing GUI in Java is a relatively easy
task.
This is also because of the Java class hierarchy architecture which includes GUI
classes. Classes of AWT such Color, Font, Graphics, Component are derived
from the Object superclass.
The Graphics Class
Graphics is an abstract class (i.e.you cannot instantiate Graphics objects). This is
because graphics is performed differently on different platforms (e.g. compare a PC with
a Mac, or a mainframe). When Java is implemented on a specific platform a derived
Graphics class is automatically created but its implementation is hidden from us inside
that derived class. In our applications we shall only use references to derived class
Graphics objects (typically we shall call them g, although you can use other names) .
The Component Class
Component is a superclass for many of the classes in AWT. Its method paint() takes a
Graphics object as an argument: public void paint (Graphics g) . Various derived classes
from Component will overwrite paint() to perform various graphics operations with the
help of the g Graphics object passes as a parameter.
A JFrame Example
To illustrate the creation of graphics in a Java application, the example below will utilize
a JFrame object, which is a common way to create GUI in stand-alone Java applications.
import java.awt.*;
import java.awt.event.*;
// Java extension packages
import javax.swing.*;
public class ShowColors extends JFrame {
// constructor sets window's title bar string and dimensions
public ShowColors() {
super( "Using colors" ); // this will put a title on the frame bar
setSize( 400, 130 );
// size in pixels
show();
}
// draw rectangles and Strings in different colors
public void paint( Graphics g ) {
// call superclass's paint method
super.paint( g );
// setColor, fillRect, drawstring, getColor, getRed etc are methods of Graphics
g.setColor( new Color( 255, 0, 0 ) ); // set new drawing color using integers for R/G/B
g.fillRect( 25, 25, 100, 20 );
g.drawString( "Current RGB: " + g.getColor(), 130, 40 );
// set new drawing color using floats
g.setColor( new Color( 0.0f, 1.0f, 0.0f ) );
g.fillRect( 25, 50, 100, 20 );
g.drawString( "Current RGB: " + g.getColor(), 130, 65 );
// set new drawing color using static Color objects
g.setColor( Color.blue );
g.fillRect( 25, 75, 100, 20 );
g.drawString( "Current RGB: " + g.getColor(), 130, 90 );
// display individual RGB values
Color color = Color.magenta;
g.setColor( color );
g.fillRect( 25, 100, 100, 20 );
g.drawString( "RGB values: " + color.getRed() + ", " +
color.getGreen() + ", " + color.getBlue(), 130, 115 );
}
// execute application
public static void main( String args[] ) {
ShowColors application = new ShowColors();
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE );
}
} // end class ShowColors
Important Notes:
The driver class defines in main() an object of the driver class type.
The driver creates an object but does not call paint(). Class JFrame has this call built in.
The only thing that is left for the driver is to provide the (optional) JFrame closing
procedure.
Positioning on a JFrame is relative to the top left corner and it is measured in pixels
(picture elements of a size which can be set by the workstation user).
Colors can be specified either through integer values (0-255) of the Red, Green and Blue
components (primary colors), or through float values (the sum of the 3 floats must be
equal to 1).
Setting the color will affect all Graphics operations (fillRect and drawstring).
Same Example as a JApplet
An alternative to JFrame is JApplet, another class part of Swing which inherits from
Component. The difference with JApplet is not only in its programming but also in the
fact that it can be executed not as a stand-alone application but as an applet by any Web
browser. Here is the same code as an applet:
Ex.3.4 ShowColors.java written as an applet
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ShowColors extends JApplet {
public void paint( Graphics g ) {
// call superclass's paint method
super.paint( g );
// set new drawing color using integers
g.setColor( new Color( 255, 0, 0 ) );
g.fillRect( 25, 25, 100, 20 );
g.drawString( "Current RGB: " + g.getColor(), 130, 40 );
// set new drawing color using floats
g.setColor( new Color( 0.0f, 1.0f, 0.0f ) );
g.fillRect( 25, 50, 100, 20 );
g.drawString( "Current RGB: " + g.getColor(), 130, 65 );
// set new drawing color using static Color objects
g.setColor( Color.blue );
g.fillRect( 25, 75, 100, 20 );
g.drawString( "Current RGB: " + g.getColor(), 130, 90 );
// display individual RGB values
Color color = Color.magenta;
g.setColor( color );
g.fillRect( 25, 100, 100, 20 );
g.drawString( "RGB values: " + color.getRed() + ", " +
color.getGreen() + ", " + color.getBlue(), 130, 115 );
}
} // end class ShowColors
Important Notes:



The use of JApplet is even simpler than with JFrame. You do not need to create
an object and the closing of the applet window.
Like with JFrame, JApplet automatically calls paint().
Another important difference between applets and frames is that the sizing and the
baptizing of the window is done in HTML instead of Java. What was done
through the constructor of the JFrame object is done for applets through the
HTML code:
// this is the file ShowColors.html
<html>
<applet code = "ShowColors.class" width = "400" height = "130">
</applet>
</html>