740 likes | 749 Views
This chapter covers generalizing classes using another class, inheritance, method overloading and overriding, class extension and composition, accessibility modifiers, scoping rules, and more.
E N D
Objectives • After studying this chapter you should understand the following: • generalizing classes by means of another class; • extension, inheritance, and the subtyping relation defined by subclasses; • method overloading, method overriding, and method polymorphism; • class extension and class composition, and their differences; • accessibility of public, private, protected, and package private features; • Java’s scoping rules. • Also, you should be able to: • define a class extending an existing class; • implement a class using an existing class via extension or composition. NH-Chapter 10
Abstraction and interfaces • An abstraction can be realized with an interface. more abstract «interface» «interface» Movable Player «interface» InteractivePlayer Weapon NH-Chapter 10
Abstraction and classes • Can define abstraction relation between classes. • Can specify that one class generalizes or abstracts another class. more abstract Figure extends is-a ClosedFigure OpenFigure generalizes Circle Rectangle more concrete NH-Chapter 10
Class extension and subtypes • Class extension creates a subtype relation between types defined by two classes. • Type Circle is a subtype of types ClosedFigure and Figure. • An expression of type Circle can be written in any context requiring a ClosedFigure or Figure. • Figure top; • Circle soleil; • (ClosedFigure)top // legal • (Circle)top // legal • (ClosedFigure)soleil // legal • (Rectangle)soleil // Not legal NH-Chapter 10
Classes and interfaces • A class can implement any number of interfaces. • An interface can extend any number of interfaces. NH-Chapter 10
Class inheritance is single inheritance • Every class extends exactly one other class. • Exception: class Object • This class is at the top (or the root) of the hierarchy, and • Has no parent. • Every class is a subclass of Object. NH-Chapter 10
Class inheritance is single inheritance • A parent class is specified with an extends clause in the class heading: publicclass Circle extends ClosedFigure { … • If a class does not specify a parent class via an extends clause, class by default extends Object. NH-Chapter 10
Class inheritance is single inheritance • If a class also implements an interface, the implements clause follows the extends clause. class Poison extends Potion implements Weapon { … } class Potion implements Movable { … } NH-Chapter 10
Extension and Inheritance publicclass ClosedFigure { private Location location; … public Location location () { returnthis.location; } publicvoid moveTo (Location newLocation) { this.location = newLocation; } … } NH-Chapter 10
Class Circle extends class ClosedFigure publicclass Circle extends ClosedFigure { … publicint radius () { … } … } NH-Chapter 10
Class Circle extends class ClosedFigure • Circle instance inherits all features of a ClosedFigure. • Private features are inherited by subclass, but not accessible from subclass. Circle circle = new Circle(10); Location loc = circle.location(); int distance = circle.radius(); this.location = null; // illegal NH-Chapter 10
Inheritance • Mechanism by which an extending class or interface automatically possesses all of the non-private features of its parent class or interface. NH-Chapter 10
Type conformance • Type Circle is a subtype of ClosedFigure. • Circle expression can be written wherever a ClosedFigure value is needed: Circle ring = new Circle(10); ClosedFigure enclosure; enclosure = ring; // legal. int distance = enclosure.radius(); // Not legal NH-Chapter 10
Type conformance • Can cast from the more abstract type to the more concrete: if (enclosure instanceof Circle) int distance = ((Circle)enclosure).radius(); NH-Chapter 10
Constructors and subclasses • Constructors are not inherited: each class must define its own constructors. • Constructor responsible for initializing instance variables in superclass and those defined in class. • First thing a constructor does is invoke a constructor of its parent class. if (enclosure instanceof Circle) int distance = ((Circle)enclosure).radius(); NH-Chapter 10
Constructors and subclasses • Assuming ClosedFigure has constructor requiring no arguments. publicclass Circle extends ClosedFigure { privateint radius; public Circle (int radius) { super(); this.radius = radius; } … } NH-Chapter 10
Constructors and subclasses • The keyword this is used in a constructor to invoke another constructor of the same class. publicclass Circle extends ClosedFigure { privateint radius; public Circle (int radius) { super(); this.radius = radius; } public Circle () { this(1); // invoke above constructor } // with argument 1. … } NH-Chapter 10
Constructors and subclasses • Extend Circle with a class ColoredCircle: publicclass ColoredCircle extends Circle { … • Constructor for ColoredCircle invokes a Circle constructor. publicclass ColoredCircle extends Circle { private Color color; public ColoredCircle (int radius, Color color) { super(radius); this.color = color; } … } NH-Chapter 10
Constructors and subclasses • Constructor that neither calls a superclass constructor explicitly nor calls another constructor of same class, it implicitly begins with super(); public ColoredCircle (Color color) { this.color = color; } • Equivalent to: public ColoredCircle (Color color) { super(); this.color = color; } NH-Chapter 10
Method overloading • Class can contain distinct methods with same name • Must differ in number and/or type of parameters. publicint report (int x) publicint report (Object obj) publicvoid report (int x, int y) NH-Chapter 10
Method overloading • A class cannot contain two methods with • same name, and • same number and type of parameters. publicvoid report (int x) public Object report (int i) // not legal NH-Chapter 10
Method overloading • Class Reporter has two methods named report: publicvoid report (Object obj) { //1 System.out.println("The argument is an object."); } publicvoid report (Circle circle) { //2 System.out.println("The argument is a circle."); } NH-Chapter 10
Method overloading • Assume reporter is an instance of class Reporter. • Circle circle = new Circle(1); • Figure figure = circle; • Object object = figure; • … • reporter.report(circle); // invokes report with parameter Circle • reporter.report(object); // invokes report with parameter Object • reporter.report(figure); // invokes report with parameter Object NH-Chapter 10
Method overloading and inheritance • Suppose class Reporter inherits a report method: class Parent {… publicvoid report (Object obj) { System.out.println("The argument is an object."); } } class Reporter extends Parent {… publicvoid report (Circle circle) { System.out.println("The argument is a circle."); } } • Class Reporter has two different report methods. • Statement below results in “The argument is an object” Object object; reporter.report(object); NH-Chapter 10
Method overloading • overloading: class with several methods with same name. • Methods are reasonably overloaded if have same function but offer alternative ways of providing arguments. • Rule : never overload a method by changing the type of a parameter to a subtype or supertype. NH-Chapter 10
Method overriding • Overriding: class redefines implementation of an inherited method. • All classes inherits method equals which is defined for class Object, and every class is a subclass of Object. NH-Chapter 10
Method overriding • Redefine equals in class Circle so that two Circles with same radius are considered equal, regardless of their locations: publicclass Circle extends ClosedFigure { … publicboolean equals (Object c) { if (c instanceof Circle) returnthis.radius() == ((Circle)c).radius(); else returnfalse; } … } NH-Chapter 10
Method overriding Object defines equals + boolean equals(Object obj) { … } inherits equals as ClosedFigure implemented in parent Circle Rectangle + boolean equals(Object obj) + boolean equals(Object obj) { … } { … } redefine equals NH-Chapter 10
Polymorphism • Which equals method is executed at * depends on the object figure1 references when the statement is reached. • BasicFileReader in = new BasicFileReader(); • ClosedFigure figure1; • ClosedFigure figure2; • int n; • in.readInt(); • n = in.lastInt(); • if (n == 0) { • figure1 = new Circle(); • figure2 = new Circle(); • } else { • figure1 = new Rectangle(); • figure2 = new Rectangle(); • } • boolean b = figure1.equals(figure2); //* NH-Chapter 10
Accessing overridden implementation • A class that overrides a method can call its parent’s implementation with key word super. • Assume class ClosedFigure defines methods moveTo and location : • publicvoid moveTo (Location newLocation) • Move this ClosedFigure to the specified Location. • public Location location () • The location of this ClosedFigure. NH-Chapter 10
Accessing overridden implementation • Suppose want to equip Circle with method to reverse most recent move: • publicvoid moveBack () • Move this Circle back to where it was before the most recent move. NH-Chapter 10
Accessing overridden implementation • We must override the inherited moveTo method, and remember the location we are moving from. publicclass Circle extends ClosedFigure { … private Location previousLocation … publicvoid moveTo (Location newLocation) { this.previousLocation = this.location(); super.moveTo(newLocation); } … } NH-Chapter 10
Overriding and Polymorphism • overriding: providing an alternative implementation of an inherited method. • polymorphism: dynamic behavior by which algorithm performed by invoked method is determined at run-time by class of object executing method. NH-Chapter 10
Overloading and Overriding • Suppose a programmer writes publicclass Circle { … publicboolean equals (Circle c) { returnthis.radius() == c.radius(); } … } • This definition overloads the equals method inherited from Object, but does not override it. NH-Chapter 10
Overloading and Overriding • Given: Circle circle1 = new Circle(1); Circle circle2 = new Circle(1); Object object2 = circle2; circle1.equals(circle2) // returns true circle1.equals(object2) // returns false • The first expression invokes method defined in Circle while second expression invokes inherited method. • circle1, and object2 are two different Object instances, then inherited method equals returns false. NH-Chapter 10
Overloading and Overriding • Suppose class Parent defines a method report, class Parent {… ¹ publicvoid report (Object obj) { System.out.println("Parent.report(Object)"); } } NH-Chapter 10
Overloading and Overriding • Method report is overridden and overloaded in subclass Child • class Child extends Parent {… • publicvoid report (Object obj) { • System.out.println("Child.report(Object)"); • } • publicvoid report (Circle obj) { • System.out.println("Child.report(Circle)"); • } • } Child child = new Child(); Parent parent = child; Circle circle = new Circle(1); parent.report(circle); • Last statement produces: “Child.report(Object)” NH-Chapter 10
Overriding and contracts • Type defined by a class is also a subtype of type defined by its parent superclass. • A subclass instance can be used where a superclass instance is expected. public void invert (ClosedFigure f) • invert can be invoked with a Circle as argument. • A subclass is obligated to respect the contract offered by its parent superclass. NH-Chapter 10
Overriding and contracts • Rules regarding precondition and postconditions and method overriding: • When overriding a method, preconditions can be weakened but cannot be strengthened. • When overriding a method, postconditions can be strengthened but cannot be weakened. NH-Chapter 10
Overriding and contracts Class ClosedFigure publicvoidfill (Color c) Paint this ClosedFigure with the specified Color. ensure:this.backgroundColor().equals(c) publicclass MonochromeFigure extends ClosedFigure • A MonochromeFigure can be supplied wherever a ClosedFigure is required. • MonochromeFigure • can override method fill, • bound to the contract as specified in ClosedFigure. NH-Chapter 10
Overriding and contracts • MonochromeFigure overrides fill : /** * Paint this MonochromeFigure black or white. * * @requirec.equals(Color.white) || c.equals(Color.black) */ publicvoid fill (Color c) { assert c.equals(Color.white) || c.equals(Color.black); … • Precondition has been strengthened, method no longer respects inherited contract. CloseFigure fig = new MonochromeFigure(); fig.fill(Color.gray); // it will fail. NH-Chapter 10
Overriding and contracts • MonochromeFigure method fill treats any non-while color as black. • publicvoid fill (Color c) • Paint this MonochromeFigure white or black. • ensure:if c.equals(Color.white)this.backgroundColor().equals(c)elsethis.backgroundColor().equals(Color.black) • Postcondition is weakened. Causes problems for ClosedFigure client expecting postconditions given in ClosedFigure to be met. NH-Chapter 10
private features access • private features are accessible from within the defined class. • publicclass Circle { • privateint r; • public Circle (int radius) { • this.r = radius; • } • publicboolean equals (Object obj) { • if (obj instanceof Circle) • ¹return r == ((Circle)obj).r; //1 • else • returnfalse; • } • publicint radius() { • return r; • } • } • At 1, private instance variable r of argument obj is accessed. NH-Chapter 10
private features access • publicclass ColoredCircle extends Circle { • private Color c; • public ColoredCircle (int radius, Color color) { • super(radius); • c = color; • } • publicboolean equals (Object obj) { • if (obj instanceof ColoredCircle) • return r == ((Circle)obj).r && //not legal access to r • c == ((ColoredCircle)obj).c; • else • returnfalse; • } • public Color color () { • return c; • } • } • consider extending Circle with a class ColoredCircle: NH-Chapter 10
private features access • Neither of the references to r in the equals method is legal. • r is private to Circle and can be accessed only in that class. • ColoredCircle does not inherit Circle private component r, thus r cannot be directly accessed in ColoredCircle. • Even casting an object to a Circle, instance variable r can be accessed only from within definition of class Circle. NH-Chapter 10
private features access • A ColoredCircle is-a Circle and cannot access r ColoredCircle obj Circle - int r + int radius() -Color c +Color color() NH-Chapter 10
private features access • The method equals can be written legally using query radius: publicboolean equals (Object obj) { if (obj instanceof ColoredCircle) returnthis.radius() == ((Circle)obj).radius() && c == ((ColoredCircle)obj).c; else returnfalse; } NH-Chapter 10
private features access • A class not labeled public is package private and can be accessed only from within its own package. • If the class is not visible outside its package, neither are any of its features. • Access to features of a nonpublic class, even if the features are labeled public, is limited to package containing class definition. NH-Chapter 10
protected features access • subclass inherits protected features, and these features are accessible in the subclass. • publicclass Circle { • protectedint r; • … • } • The references to r in subclasses are legal. NH-Chapter 10