COP 3330: Object-Oriented Programming Summer 2007 Inheritance and Polymorphism – Part 1. Instructor : Mark Llewellyn [email protected] HEC 236, 823-2790 http://www.cs.ucf.edu/courses/cop3330/sum2007. School of Electrical Engineering and Computer Science - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
• The concept of inheritance is important in the design of software systems.
– It provides a way of organizing the components of the system in a hierarchical manner. The hierarchy helps one to understand the system.
– In addition, it provides a framework for reusing code.
• Inheritance is used typically to organize abstractions in a top-down fashion from the most general (least specific) to the least general (most specific). Consider the hierarchy shown in the next slide.
• The partial car hierarchy shown in the previous slide illustrates the hierarchical concept of moving from the general to the specific as you move down the hierarchy.
– The hierarchy is organized according to different manufacturers of cars and their various models.
– Understanding the hierarchy enables one to recognize and distinguish shared and distinguishing characteristics of different types of cars.
– At the top of the hierarchy is the most general representation, which in this specific hierarchy is simply a car.
– According to the hierarchy, cars fall into one of four categories: BMW, Mercedes, Ferrari, and Porsche.
– Within the specific category of Mercedes cars (moving down the hierarchy), we see that Mercedes cars are further classified into one of three subcategories: C-class, E-class, and S-class.
– Moving even further down the hierarchy, we see that the subcategory of E-class Mercedes are again further classified into one of three sub-subcategories: E-350, E-500, and E-500-AMG categorized depending upon the various features of each model.
– Therefore, we can look at E-350s differently than E-500s, yet they share all of the characteristics of an E-class model and similarly they share all of the characteristics of a Mercedes, and so on, up the hierarchy.
• In object-oriented programming languages, a class created by extending another class is known as a subclass.
• The class used as a basis for a subclass is its superclass.
– Sometimes a superclass is also referred to as a base class and the subclass is then referred to as the derived class.
• In general, a subclass can provide both additional data fields and methods. This is illustrated in the next slide using the car hierarchy from page 3.
E-350s are type of E-class; i.e., they are a subcategory of E-class models. In programming terminology they are a subclass of the class E-class models.
E-class models are a type of Mercedes; i.e., they form a subclass of Mercedes cars.
Mercedes’ are a type of car; i.e., they form a subclass of cars. According to the hierarchy on page 3, there are three other subclasses of cars that have been identified.
• One complication with regard to inheritance for beginning OO programmers is the fact that a subclass object has multiple types.
• The subclass object is a specialized superclass type object. Therefore, the subclass object is of both the subclass and superclass types.
• With inheritance, there is an is-a relationship between the subclass type and its superclass type. For example, an E-320 is an E-class and it is also a Mercedes.
• Now let’s change our focus from the simple concept of inheritance to using inheritance as a programming mechanism.
• We’ll start off by using inheritance to extend a built-in Java class and then move on into extending classes that we’ll construct ourselves.
• For starters, we’ll extend the awt class to support several different application needs. In particular, we’ll extend Java’s Point class that we have used in previous examples in the course.
• The awt class Point provides a representation of a 2-dimensional point. We’ve used this class before (see ??? for example).
• Using inheritance we will build upon this 2-dimensional point representation to create a 3-dimensional point class representation, ThreeDPoint. The new class ThreeDPoint extends class Point by adding a new property that the Point class does not have, namely, a z-coordinate value.
• This new property can be maintained by using a public data field z. To support encapsulation and information hiding, ThreeDPoint provides an accessor method getZ() and a mutator method setZ() for the new z-coordinate property.
• Since we are extending the class ThreeDPoint from Point. ThreeDPoint inherits the Point x-coordinate and y-coordinate attributes and Point accessor and mutator methods getX(), getY(), setX(), and setY().
– We’ll use these accessors and mutators in our implementation of ThreeDPoint. The use of these methods is not strictly necessary because the Point class makes its attributes public (which is also why we made coordinate z a public data field). Our implementation uses these methods because the use of mutators and accessors is a good practice – superclass attributes are almost always private (the Point class is a rare exception to this rule). In the typical case, a subclass cannot directly access the attributes, and instead must use the available superclass accessors and mutators to manipulate the superclass attributes.
• Unless we indicate otherwise, the ThreeDPoint class also inherits the Point class facilitators, e.g., translate(), toString(), equals(), and clone(). However, these Point facilitators are not suitable in a 3-dimensional context – they aren’t aware of the z-coordinate values. Therefore, the ThreeDPoint class must provide its own versions of these methods .
• Remember that all classes are either explicitly or implicitly an extension of the class Object. The relationship between ThreeDPoint, Point, and Object are illustrated in the following diagram.
ThreeDPoint Point Object
Class representing locations with x-, y-, and z- coordinates.ThreeDPoint is a subclass ofPoint.
Class representing locations with x- and y- coordinates.Point is a subclass of Object.
Superclass of all Javaobjects.
Class Object provides basic versions of several methods including: toString(), equals(), and clone(). It also has methods finalize(), getClass(), hashCode(), notify(), notifyAll(), and wait(). These are all inherited by the subclasses of Object.
• The ThreeDPoint method translate() will have three parameters representing the increment in the x, y, and z coordinates.
• Since the method signatures of the ThreeDPoint and Point versions of translate() are different, the method name translate() is overloaded in the ThreeDPoint class.
– This means that with a ThreeDPoint object both methods are available. Java determines which method is in use by the number of parameters in a given invocation.
ThreeDPoint a = new ThreeDPoint(5, 20, 47);a.translate(1,1); //invocation of superclass translatea.translate(2,2,2); //invocation of subclass translate
ThreeDPoint Class Methods toString(), equals(), and clone()
• The ThreeDPoint methods toString(), equals(), and clone() should not have different signatures from the Point versions.
– By having the same signatures as their superclass counterparts, the subclass methods override the superclass definitions for ThreeDPoint objects. The overriding enables the subclass-specific nature of the ThreeDPoint objects to be considered.
ThreeDPoint c = new ThreeDPoint(1, 3, 5);ThreeDPoint d = (ThreeDPoint) c.clone();//cast is necessary//as apparent type of return value of subclass method clone() is Object String s = c.toString(); //invocation of subclass toString() methodboolean b = c.equals(d); //invocation of subclass equals() method
//getZ(): z-coordinate accessor public double getZ(){ return z;
} //setZ(): z-coordinate mutator public void setZ(int value){ z = value; }
//translate(): shifting facilitator public void translate(int deltax, int deltay, int deltaz){ translate(deltax, deltay); int zValue = (int)getZ(); setZ(zValue+deltaz); }
//toString(): conversion facilitator public String toString(){ int a = (int)getX(); int b = (int)getY(); int c = (int)getZ();
return getClass() + “[“ + a + “,” + b + “,” + “,” + c + “]”;}
//equals(): equality facilitator public boolean equals(Object v){ if (v instanceof ThreeDPoint){ ThreeDPoint p = (ThreeDPoint) v; int z1 = (int) getZ(); int z2 = (int) p.getZ(); return super.equals(p) && (z1 == z2); } else { return false; } }
//clone(): cloning facilitator public Object clone(){ int a = (int) getX(); int b = (int) getY(); int c = (int) getZ(); return new ThreeDPoint(a,b,c); }}//end class ThreeDPoint
• ThreeDPoint begins with a package statement. A package statement indicates that the definitions that follow are part of a bigger collection known as a package. In this case, the bigger package is called geometry.
package geometry;
Keyword package indicates that the definitions that follow are part of a package. An element of a package has special access rights with regards to the other elements of the package.
• We have used packages (e.g., swing, awt, math, and io) in many of the sample programs we written. However, class ThreeDPoint is the first class that we have defined to be part of a package.
• Programmers put classes and interfaces into a package for two basic reasons:
1. Organization: By organizing classes and interfaces with a related purpose into a package, you make it easier for users to find them – classes and interfaces with the same package name are stored in the same folder. In addition, Java puts the classes of one package in a different namespace (scope) than it puts the classes of another package. As a result, the names in a package do not conflict with names in other packages.
2. Special access to members: When defining members of a class or interface, Java does not require an explicit access specification. The implicit specification is known as default access. Members of a class with default access can be accessed only by members of the package.
• If a Java files does not begin with a package statement, then all the definitions in that file are considered to be part of a package unique to that file.
• Because a ThreeDPoint object is an extended version of a Point object, the construction of a ThreeDPoint object begins with the construction of its superclass attributes (i.e., x- and y- coordinate values).
• To initialize these attributes, a superclass constructor must be invoked. The superclass invocation can be explicit or implicit.
• Since a subclass is a specialization of the superclass, a constructor for the superclass must be invoked to create a superclass object before the constructor for the subclass can do its specialization. (Parallel – if you are going to build a Mercedes E-350 you don’t start out on a Ford assembly line!)
• This statement from the ThreeDPoint default constructor definition is an explicit invocation of the superclass’s default constructor on the object under construction.
• Since the superclass of ThreeDPoint is Point, it is the Point default constructor that is invoked for the object under construction.
• The Point default constructor takes care of the initialization of the x- and y- coordinate values. This action is the only explicit work required for the initialization process, because z- coordinate instance variable definition specifies the initial value for instance variable z.
• The other ThreeDPoint constructor initializes the object under construction to the given x-, y-, and z- coordinate values. This constructor also explicitly invokes a superclass constructor.
• The invocation uses the Point constructor to properly set the x- and y- coordinate values. To complete the initialization, the z- coordinate is set to the desired values using mutator setZ();
• If a subclass constructor does not invokes explicitly a superclass constructor, then Java automatically invokes the superclass’s default constructor to initialize the superclass attributes.
– This means that we could have written our ThreeDPoint default constructor definition without explicitly invoking super().
– Since it is simpler to omit the explicit invocation than to type it in, most constructor code makes use of the implicit invocation of super().
public ThreeDPoint() { //implicit super() invocation before //mutator invocation}
• Notice that the constructors in the ThreeDPoint class are both quite short. This is possible since we are able to reuse the code that was developed for the superclass.
• With this small example, the savings in code may not be that great, but with more complex classes, the savings can be substantial.
//translate(): shifting facilitator public void translate(int deltax, int deltay, int deltaz){ translate(deltax, deltay); int zValue = (int)getZ(); setZ(zValue+deltaz); }
Method translate() of Class ThreeDPoint
• ThreeDPoint method translate() uses the superclass method translate() to assist in the shifting of position. However, the keyword super is not required to invoke the superclass translate() method because the superclass version uses two parameters and the subclass version uses three parameters.
• Java can determine from context that it is the superclass method translate() that is being invoked.
Because there are two parameters present, it is the
ThreeDPoint c = new ThreeDPoint();c.translate(2,2,2);ThreeDPoint d = new ThreeDPoint(1,2,3);ThreeDPoint e = (ThreeDPoint) d.clone();System.out.println(c);System.out.println(d);System.out.println(e);System.out.println(d.equals(c));System.out.println(d.equals(e));
Using the Class ThreeDPoint• The following code segment illustrates some of the uses of the
class ThreeDPoint.
• This code segment produces the output:class.geometry.ThreeDPoint[2,2,2]class.geometry.ThreeDPoint[1,2,3]class.geometry.ThreeDPoint[1,2,3]falsetrue
Another Extension of the Point Class• Suppose an application calls for the use of colored points. For
example, we can use colored points to represent the pixels of some image. Once again the principle of inheritance can be used to create a class to represent colored points.
• As we did with the class ThreeDPoint, we’ll extend the Point class in a natural manner to provide a representation of a colored point. We’ll define a class called ColoredPoint.
• The class will add a data field color to represent the color attribute and an appropriate accessor and mutator for that property.
• The class will also need to provide overrides for equals(), clone(), and toString().
//equals(): equality facilitator public boolean equals(Object v){ if (v instanceof ColoredPoint){ Color c1 = getColor(); Color c2 = ((ColoredPoint) v).getColor();
//clone(): cloning facilitator public Object clone(){ int a = (int) getX(); int b = (int) getY(); Color c = getColor(); return new ColoredPoint(a,b,c); }}//end class ColoredPoint
Using the Class ColoredPoint• The following code segment illustrates some of the uses of the
class ColoredPoint.
• This code segment produces the output:
ColoredPoint c = new ColoredPoint();ColoredPoint d = new ColoredPoint(1,2, Color.Black);ColoredPoint e = (ColoredPoint) d.clone();System.out.println(c);System.out.println(d);System.out.println(e);System.out.println(d.equals(c));System.out.println(d.equals(e));
• Suppose an application calls for the use of colored, 3-dimensional points. The question is whether you can create a class Colored3DPoint that extends from both ThreeDPoint and ColoredPoint?
– The answer in Java is no.
• Java supports single inheritance, it does not support multiple inheritance.
• Due to the complex nature of multiple inheritance, the designers of Java decided explicitly not to support multiple inheritance.
Problems of Multiple Inheritance• To illustrate a fundamental problem with multiple
inheritance consider the following situation.
– Suppose we were to create a class Colored3DPoint by extending it from both ThreeDPoint and ColoredPoint. Should the new class have two sets of x- and y- coordinate values because ThreeDPoint and ColoredPoint both have x- and y- coordinate values? On the other hand, should it have one set of x- and y- coordinate values because ThreeDPoint and ColoredPoint are both extended from Point?
• Rather than force programmers to deal with situations like the one described above, Java does not permit multiple inheritance.
• Thus, if we want to define a class Colored3DPoint, we would need to do one of the following:
1. Extend ThreeDPoint to provide a color attribute. In this case Colored3DPoint becomes a subclass of ThreeDPoint which is already a subclass of Point. This case is illustrated by the code which begins on the next page.
2. Extend ColoredPoint to provide a z- coordinate attribute. In this case Colored3DPoint becomes a subclass of ColoredPoint which is already a subclass of Point. You should try this extension yourself to become more familiar with inheritance in Java.
//getColor(): color property accessor public Color getColor(){ return color;
} //setColor(): color property mutator public void setColor(Color c){ color = c; }
//toString(): string representation facilitator public String toString(){ int a = (int)getX(); int b = (int)getY(); int c = (int)getZ(); Color d = getColor();
return getClass() + “[“ + a + “,” + b + “,” + “,” + c + “,” + d +“]”;}
//equals(): equality facilitator public boolean equals(Object v){ if (v instanceof Colored3DPoint){ Color c1 = getColor(); Color c2 = ((Colored3DPoint) v).getColor();
//clone(): cloning facilitator public Object clone(){ int a = (int) getX(); int b = (int) getY(); int c = (int) getZ(); Color d = getColor(); return new Colored3DPoint(a,b,c,d); }}//end class Colored3DPoint
Why Not Add To Classes Rather Than Extend Classes?
• Why bother with inheritance at all? Why not just modify the existing class to include the new features? For example, why not give the Point class a z-coordinate value?
– Simply adding features can make a class too complex to understand or build. Imagine if such an approach were taken in the construction of a car from our earlier example. Our car class would be too unwieldy to use effectively.
– Another factor that should discourage adding to a class is user confidence and cost. Complex classes are difficult to build, maintain, and test. Programmers are understandably skeptical regarding the use of a massive API. Furthermore, if the source code to an existing class is not available, then adding new features to that class is not an option. Most libraries are distributed as compressed archives or as .class files with .java versions unavailable – developers often keep the .java versions to themselves to protect their intellectual investment.