Inheritance

! Two things which are different at one level are similar or equivalent at a more abstract level. ! Upper classes are more abstract; lower classes are more concrete. Chapter 10 ! The more concrete "subclass" extends the more abstract "superclass" and inherits the functionality of the superclass. ! The abstract class generalizes or abstracts the concrete class.

2

Inheritance … Inheritance …

! Recall that abstraction can be realized with an interface. ! An interface generalizes a class or less abstract interface. ! We can also define the abstraction relation between classes. ! The more concrete interface extends the more abstract interface. ! One class can generalize (or abstract) another class. ! Weapon extends Movable ! The more concrete class extends the more abstract class. ! The more concrete class implements the more abstract interface. ! extends ! InteractivePlayer implements Player ClosedFigure Figure ! 3 Circle extends ClosedFigure 4

Inheritance … Inheritance …

! The more concrete class extends the more abstract class. ! The more abstract class generalizes the more concrete class. ! Circle extends ClosedFigure ! ClosedFigure generalizes Circle ! Circle is-a ClosedFigure ! ClosedFigure is an abstraction of Circle ! Circle is a subtype of ClosedFigure ! ClosedFigure is a supertype of Circle ! ! Circle is a descendant of ClosedFigure 5 ClosedFigure is an ancestor of Circle 6 Inheritance … Inheritance …

! Class extension defines a subtype. ! As with interfaces, class extension creates a subtype relation between the types defined by the two classes. ! Expression can be cast up or down the class hierarchy. ! Given the following variable declarations: Figure top; Circle bottom; ! The following are legal (though not necessarily safe) expressions: ! Class extension is a transitive relation. (ClosedFigure) top // downward cast ! Circle extends Figure, etc. (Circle) top // downward cast ! Figure generalizes Circle, etc. (ClosedFigure) bottom // upward cast ! This is not legal: 7 (Rectangle)X bottom 8

Inheritance … Inheritance …

! There is one significant difference ! The Object class is at the top (or root) of the hierarchy, and has no between extending or implementing parent. an interface, and extending a class. ! Every other class is a subclass of Object. ! A parent class is specified with an extends clause in the class ! A class can implement, and an heading. interface can extend, any number ! The definition of Circle looks like: of interfaces. public class Circle extends ClosedFigure { ! A class can have any number of … “interface parents”. } ! Every class (except the Object ! Omitting the extends clause in a class definition: class) extends exactly one other public class Figure { class. … ! Single inheritance } is equivalent to: public class Figure extends Object { 9 … 10 }

Extension and inheritance Inheritance …

! An interface defines a set of features that are guaranteed to be ! If a class implements an interface, provided by an implementing class. the implements clause follows the ! Since the interface contains no implementation, the implementing extends clause. class is required to implement the features.

! The definition of Poison and ! This situation is somewhat different with a class. Potion look like: ! As with an interface, the generalizing class defines a set of features that are guaranteed to be provided by an extending class. ! But the generalizing class already has implementations for its public class Poison extends Potion implements Weapon { features. … ! The extending class inherits the public features of the generalizing } class. public class Potion implements Movable { ! The extending class does not need to independently implement these inherited features. … } 11 Extension and inheritance … Extension and inheritance …

! Class extension: ! the mechanism provided by the language for implementing public class ClosedFigure { abstraction. ! Inheritance: private Location location; ! a mechanism by which a subclass automatically possesses all of the non-private features of its superclass. public Location location () { return this.location; }

public void moveTo (Location newLocation) { this.location = newLocation; }

}

Extension and inheritance … Extension and inheritance …

public class Circle extends ClosedFigure { ! A subclass does not “inherit” private features of its superclass. … ! The variable location is private to ClosedFigure. public int radius (){ ! It cannot be directly accessed from . … Circle } ! Illegal within a method of Circle: } this.locationX = null; ! location can be indirectly accessed from Circle. ! Legal within a method of : Circle circle = new Circle(10); Circle Location loc = circle.location(); this.moveTo(null); int distance = circle.radius();

Subtyping and inheritance Subtyping and inheritance …

! The type Circle is a subtype of ClosedFigure. ! Type conformance rules are static. ! The rules for type conformance are the same, regardless of whether ! Thus we are not permitted to write: the type is defined by a class or an interface. distance = enclosure.radius(); ! Thus a Circle expression can be written wherever a X ClosedFigure value is needed: even if we are sure that enclosure will in fact reference a Circle Circle ring = new Circle(10); when the statement is executed. ClosedFigure enclosure; ! A ClosedFigure is not necessarily a Circle. enclosure = ring; ! A ClosedFigure does not have a radius() method.

! This is OK since Circle is a subtype of ClosedFigure. ! We can, of course, cast from the more abstract type to the more concrete: if (enclosure instanceof Circle) { distance =((Circle)enclosure).radius(); } DrJava Example Constructors and subclasses

! Let’s look at class extension in more detail in DrJava ! Constructors are not inherited. ! The constructor is responsible for initializing components defined in a superclass as well as those expressly defined in the class itself. ! The first thing that a constructor must do is invoke the constructor of its parent (super) class. ! A constructor can also invoke another constructor of the same class: this(arguments); ! A superclass constructor can be called: super(arguments); ! Constructor invocations via this() and super() can only appear as the first statement of another constructor.

19 20

Constructors and subclasses … Constructors and subclasses …

public class Circle extends ClosedFigure { public class ColoredCircle extends Circle { private Color color; private int radius; public ColoredCircle (int radius, Color color) { super(radius); // invoke super 1-arg constructor public Circle (int radius) { this.color = color; super(); // invoke super no-arg constructor } this.radius = radius; public ColoredCircle (Color color) { } // implicitly calls no-arg super constructor this.color = color; public Circle () { } … this(1); // invoke above constructor } } ! Note that for this to be valid, Circle must have a 1-arg and a no-arg … 21 constructor. 22 }

Constructors and subclasses … Constructors and subclasses …

! If no constructor is called for a superclass, and no constructor of the ! If a class definition doesn’t contain any constructor definitions then a same class is called, the constructor is assumed to begin with the default constructor requiring no arguments is automatically created. invocation of the superclass constructor super(); ! The default constructor is equivalent to: public ColoredCircle (Color color) { // implicitly calls no-arg super constructor public Class () { this.color = color; super(); } }

! This is equivalent to: public ColoredCircle (Color color) { super(); this.color = color; }

23 24 DrJava Example Method overloading

! Let’s look at constructors in more detail in DrJava ! A class can contain distinct methods with the same name as long as invocations of these methods can be distinguished by the compiler. ! Overloading ! Each overloaded method must differ from each other in the number and/or type of its parameters. public int report (int x) public int report (Object obj) public void report (int x, int y) ! These are completely separate, independent methods. ! The number and types of arguments determine which method is invoked. ! report(2) invokes the first, report(“2”) invokes the second, and report(2,3) invokes the third

25 26

Method overloading … Method overloading …

! Note that a class cannot contain two methods with the same name ! Overload resolution is static. and the same number of parameters, even if the methods have different return types. ! The method to be executed is determined by the compiler based on the static types of the argument expressions. ! Because Java supports coercion (implicit type conversion) and subtyping, it is not always possible to differentiate methods that ! It does not depend on the actual run-time argument values. differ only by their return type. ! Suppose a class Reporter has two methods named report defined as follows: ! A class cannot contain the following method definitions (even though one is a query returning an Object and the other is a command): public void report (Object obj) { public void report (int x) System.out.println(“The argument is an object.”); public Object report (int i) } X public void report (Circle circle) { System.out.println(“The argument is a circle.”); }

27 28

Method overloading … Method overloading …

! Assume is a subclass of and consider the following Circle Figure ! Which method is invoked for each of these calls? definitions and initializations: Circle circle = new Circle(1); reporter.report(circle); public void report (Object obj) { Figure figure = circle; System.out.println reporter.report(object); (“The argument is an object.”); Object object = figure; } reporter.report(figure); ! Note that all three references contain public void report (Circle circle) { have the same value: System.out.println (“The argument is a circle.”); } ! Given the declaration Reporter reporter; consider the following statements: reporter.report(circle);

reporter.report(object); 29 30 reporter.report(figure); Method overloading … Method overloading …

! Use overloading judiciously. ! The library class java.io.PrintStream contains ten different ! A good rule is never overload a method by changing the type of a println() methods: parameter to a subtype or supertype. public void println (String x) ! Some adhere to an even more conservative policy – never overload two methods with the same number of parameters. public void println (Object x) ! Methods are reasonably overloaded if they have the same function but public void println (int x) offer alternative ways of providing arguments. public void println (long x) ! Suppose we want a method that moves a figure to a particular point in a window. public void println (float x)

! We might allow the client to provide the location by giving x, y public void println (double x) Cartesian coordinate: public void println (boolean x) public void moveTo (int x, int y) public void println (char x) ! We might also allow the client to provide the location by explicitly public void println (char[] x) specifying the point: 31 32 public void moveTo (Point newLocation) public void println ()

DrJava Example Method overloading …

! Let’s look at overloading in more detail in DrJava ! Methods are also overloaded to provide default parameter values. ! For example, we might offer two methods for coloring a circle, one in which the color is explicitly given and one in which a default value is used: public void fill (Color color) public void fill () ! The String class contains two methods for extracting a substring, one in which the client specifies the end of the substring and one in which the default (of the end of the string) is used: public String substring (int beginIndex) public String substring (int beginIndex, int endIndex)

33 34

Method overriding Method overriding …

! We have seen that a subclass inherits all the (public) features of its ! A class can redefine the implementation of a method that it inherits. parent class. ! Such a redefinition is called overriding. ! For instance, every Java class comes equipped with an equals() method that is effectively defined as: ! The redefinition must have the same number and type of parameters public boolean equals (Object obj) { as the original (inherited) definition. return this == obj; ! The return type of the redefinition must be the same as the original } return type (or a subtype of the original return type). ! The reason every class has this method is that the equals() ! Note that the parameters must be the same types to be overridden, method is defined for the class Object, and every class is a but the return types can be subtypes subclass of Object. ! If the parameters are subtypes then the method is not overridden, but rather is overloaded

35 36 Method overriding … Method overriding …

! For instance, we might redefine the equals() method in the Circle class so that two circles with the same radius are considered equal: public boolean equals (Object c) { return c instanceof Circle && this.radius() == ((Circle)c).radius(); } ! We might redefine the equals() method in the Rectangle class so that two rectangles with the same length and width are considered equal: public boolean equals (Object r) { return r instanceof Rectangle && this.length() == ((Rectangle)r).length() && this.width() == ((Rectangle)r).width();

} 37 38

Method overriding … Method overriding …

public class Circle extends ClosedFigure { ClosedFigure f1; … ClosedFigure f2; public boolean equals (Object c) { return c instanceof Circle && Scanner in = new Scanner(System.in); this.radius() == ((Circle)c).radius(); int n = in.nextInt(); } if (n == 0) { … f1 = new Circle(); } f2 = new Circle(); public class Rectangle extends ClosedFigure { } … else { public boolean equals (Object r) { f1 = new Rectangle(); return r instanceof Rectangle && f2 = new Rectangle(); this.length() == ((Rectangle)r).length() && } this.width() == ((Rectangle)r).width(); } boolean b = f1.equals(f2);

… 39 40 }

Method overriding … Method overriding …

! polymorphism: ! The abstract takeTurn() method is inherited and overridden in each ! dynamic behavior by which the method performed as the result of a implementing class. call to a given object is determined at run-time by the class of the ! Each class provides its own implementation of the object. takeTurn() method, exactly as Circle and Rectangle provide their own ! Polymorphism applies to classes in the same way it applies to implementations of the equals() method. interfaces. ! When the following statement: ! Recall that the Player interface was implemented by several classes: nextPlayer.takeTurn(pile, MAX_ON_A_TURN); TimidPlayer is executed, the actual method that is performed GreedyPlayer takeTurn() depends on the object that nextPlayer references. CleverPlayer ! Unlike overload resolution, override resolution is dynamic. ! The Player interface defines the takeTurn() method: public void takeTurn (Pile pile, int maxOnATurn);

41 42 Method overriding … Method overriding …

! A class that overrides a method can call its parent’s overridden ! Recall the ClosedFigure class that defines the following moveTo() implementation with the keyword super. and location() methods: ! Consider the following implementation: public void moveTo (Location location) public class Circle extends ClosedFigure { Move this ClosedFigure to the specified Location. … private Location previousLocation; public Location location () … The location of this ClosedFigure. public void moveTo (Location newLocation) { this.previousLocation = this.location(); ! Suppose we want the Circle subclass of the ClosedFigure class to super.moveTo(newLocation); contain a moveBack() method that reverses its previous move: } public void moveBack () public void moveBack () { Move this Circle back to where it was before the most recent moveTo(previousLocation); move. } 43 … 44 }

Method overriding … Method overriding …

! Overloading and overriding are different aspects of the language. ! Overloading and overriding are easily confused. ! Overloading involves several distinct methods with the same name ! Consider the following attempt to override the equals() method of in a single class. the Object class: ! Which method is invoked is determined by the compiler, and public class Circle extends ClosedFigure { depends on the (static) type of the argument expressions. … ! Overriding involves a single method with different implementations public boolean equals (Circle c) { in different classes. return this.radius() == c.radius(); ! Which implementation is performed depends on the object } executing the method at run-time. … } ! This definition overloads the equals() method inherited from Object, but it does not override it.

45 46

Method overriding … Method overriding …

! Given: ! With the above definition of equals(), the Circle class has two distinct methods named equals(): Circle circle1 = new Circle(1); Inherited from Object Circle circle2 = new Circle(1); public boolean equals (Object obj) { Object object2 = circle2; return this == obj; ! The following evaluates to true: } circle1.equals(circle2) Explicitly defined here ! The following evaluates to false: public boolean equals (Circle c) { circle1.equals(object2) return this.radius() == c.radius(); }

47 48 Method overriding … Method overriding …

! Casting changes the static type of the expression, and hence the ! The intent of equals() method is to determine if the content of two method to be invoked. objects is the same. ! The following evaluates to false: ! The behavior of equals() in the Object class is identical to == circle1.equals((Object)circle2) ! We normally override equals() to test the content of the objects, ! The following evaluates to true: that is, to do a field by field comparison. circle1.equals((Circle)object2) ! Rules for overriding equals(): ! x.equals(x) should return true ! What does object2.equals(circle1) evaluate to? ! If x.equals(y) returns true, then y.equals(x) should also return true ! If x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true ! x.equals(null) should return false

49 50

Method overriding … Method overriding …

! The equals() method of the Object class has the following //************************************************************* signature: // Student.java - A college student. //************************************************************* public class Student { public boolean equals (Object o); private String name; private int numCourses; Note that the parameter type is Object, thus casting will be required. //------// Creates a student with the name and number of courses. //------public Student (String name, int numCourses) { this.name = name; this.numCourses = numCourses; }

public String toString () { String result = "Student name: " + name + "\n"; result += "Number of courses: " + numCourses; return result; 51 52 } }

Method overriding … Method overriding …

//************************************************************* //************************************************************* // GradStudent.java - A graduate student, with financial support. // Student.java - A college student. //************************************************************* //************************************************************* public class GradStudent extends Student { public class Student { private String source; private double rate; private String name; //------private int numCourses; // Creates a gradate student using the specified information. //------public boolean equals (Object stu) { public GradStudent(String name, int numCourses, String source, double rate) { super(name, numCourses); return (this == stu) // parameter is same object or this.source = source; || ((stu != null) // it points to a real object & this.rate = rate; && (getClass().equals(stu.getClass())) // not from a subclass & } && (name.equals(((Student)stu).name)) // contents are equal public String toString () { && (numCourses == ((Student)stu).numCourses)); String result = super.toString(); } result += "\nSupport source: " + source + "\n"; result += "Hourly pay rate: " + rate; return result; } } 53 54 } Method overriding … Method overriding …

//************************************************************* ! Now consider a case involving both overloading and overriding. // GradStudent.java - A graduate student, with financial support. ! Suppose the class defines a method named : //************************************************************* Parent report() public class GradStudent extends Student { public class Parent { private String source; … private double rate; public void report (Object obj) { public boolean equals(Object gStu) { System.out.println(“Parent.report(Object)”); return (this == gStu) // parameter is same object or || ((gStu != null) // it points to a real object and } && (getClass().equals(gStu.getClass())) // it is not from a subclass & … && (super.equals(gStu)) // their base contents are equal & && (source.equals(((GradStudent)gStu).source)) // their derived } && (rate == ((GradStudent)gStu).rate)); // contents are equal } }

55 56

Method overriding … Method overriding …

! Given: ! We will overload and override the report() method in the Child subclass: Child child = new Child(); public class Child extends Parent { Parent parent = child; Child.report(Object) Overridden method … Circle circle = new Circle(); public void report (Object obj) { ! What does the command parent.report(circle) produce? System.out.println(“Child.report(Object)”); ! The expression parent is of type Parent and the Parent class has only } one report() method so there is no overload resolution to worry about. Overloaded method ! The report() method of Parent requires an Object as argument and circle is a subtype of Object (so that is acceptable). public void report (Circle c) { ! But the report() method that requires an Object as argument is System.out.println(“Child.report(Circle)”); overridden in the Child subclass. } ! And parent actually references a Child when the command is executed so the overridden implementation is executed. … 57 58 }

DrJava Example Overriding and contracts

! Let’s look at overriding in more detail in DrJava ! Recall that a class implementing an interface is obligated to respect the contract offered by the interface. ! This is necessary because the type defined by the class is a subtype of the type defined by the interface. ! The type defined by a class is also a subtype of the type defined by its parent superclass ! A subclass instance can appear anywhere that a superclass instance is expected. ! Hence a subclass is obligated to respect the contract offered by its parent superclass.

59 60 Overriding and contracts … Overriding and contracts …

! Rules regarding preconditions and postconditions: public class ClosedFigure extends Object { ! When overriding a method, preconditions can be weakened but … cannot be strengthened. /** ! When overriding a method, postconditions can be strengthened * Paint this ClosedFigure with the specified but cannot be weakened. * color. * * @require true * @ensure this.backgroundColor().equals(c) */ public void fill (Color c) { … } 61 … 62 }

Overriding and contracts … Feature accessibility

! To this point, all the features defined for a class: public class MonochromeFigure extends ClosedFigure { ! methods … /** ! instance variables * Paint this MonochromeFigure black or white. Cannot strengthen * ! named constants precondition * @require c.equals(Color.white) || have been labeled either public or private. * c.equals(Color.black) * X ! Public features are part of the class specification and are visible to * @ensure c.equals(Color.white) ? clients of the class. * this.backgroundColor().equals(c) : ! Private features are part of the implementation and are not * this.backgroundColor().equals(Color.black) X Cannot weaken available to clients. */ postcondition public void fill (Color c) { … } … 63 64 }

Feature accessibility … Feature accessibility …

! Java provides two other accessibility categories for class features: ! Feature accessibility has to do with the structure of the program text and not with the run-time state of the system. ! protected

! Protected features are intended to be inherited by and ! Static feature rather than a dynamic feature. accessible in a subclass ! One asks “From where in the program text can this feature be

! package private (or restricted) accessed?” rather than “Which objects can access this feature?”

! Package private features are accessible in the class’s package.

65 66 Feature accessibility … Feature accessibility …

! Given: ! Consider the following class definition for Circle: Circle c1 = new Circle(10); public class Circle extends ClosedFigure { Circle c2 = new Circle(12); private int r; public Circle (int radius) { ! c1 and c2 are two distinct instances of the class Circle, each with their own instance variable . super(); r this.r = radius; ! Consider the following expression: } c1.equals(c2) public boolean equals (Object obj) { ! Now c1 will execute the Circle method equals(), and legally return (obj instanceof Circle) && access the private instance variable r of c2. this.r == ((Circle)obj).r; ! All private features of Circle, including the private instance variable } r, of any Circle, can be referenced from anywhere in the context of public int radius () { Circle. return r; } 67 68 }

Feature accessibility … Feature accessibility …

! Consider the following class definition for ColoredCircle: ! Note that both the ColoredCircle instance executing the equals() public class ColoredCircle extends Circle { method and the method argument obj are both Circle objects (because all ColoredCircle objects are Circle objects). private Color c; public ColoredCircle (int radius, Color color) { ! Further note that Circle objects have a private instance variable name r. super(radius); this.c = color; ! Neither reference to r in the equals() method are legal. } ! r is private to Circle and can be accessed only from inside that public boolean equals (Object obj) { class. return (obj instanceof ColoredCircle) && ! Since ColoredCircle does not inherit the private instance this.r == ((Circle)obj).r && variable r from Circle, r cannot be directly accessed from ColoredCircle. this.c.equals(((ColoredCircle)obj).c); } X X ! Notice that even casting the ColoredCircle to a Circle does not enable one to access r within ColoredCircle. public Color color () { return c; } 69 70 }

Feature accessibility … Feature accessibility …

! Another solution to this problem is to invoke the superclass’ equal() ! One solution to this problem is to use the public method radius(): method: public class ColoredCircle extends Circle { public class ColoredCircle extends Circle { private Color c; private Color c; public ColoredCircle (int radius, Color color) { public ColoredCircle (int radius, Color color) { super(radius); super(radius); this.c = color; this.c = color; } } public boolean equals (Object obj) { public boolean equals (Object obj) { return (obj instanceof ColoredCircle) && return (obj instanceof ColoredCircle) && this.radius() == ((Circle)obj).radius() && super.equals(obj) && this.c.equals(((ColoredCircle)obj).c); this.c.equals(((ColoredCircle)obj).c); } } public Color color () { public Color color () { return c; return c; } 71 } 72 } } Protected features Feature accessibility …

! A protected feature is labeled protected: ! A class that does not have a visibility modifier is package private and can be accessed only from within its own package. protected int r; ! If a class is not visible outside its package then neither are any of ! A subclass inherits protected features, and these features are its features. accessible in the subclass. ! Even if the features are labeled public, they are limited to the ! Declaring a feature protected extends its visibility considerably. package containing the class definition. ! A feature declared protected is accessible from anywhere in the ! Visibility of the class supercedes the visibility of its features. package containing the class in which the feature is defined. ! A package private class usually serves as a supporting class for ! Protected features should be considered part of the contract a class some public class. offers to its subclasses, rather than features to be accessed by other clients.

73 74

Protected features … Protected features …

! A protected feature is inherited, so every ! The instance variable that is declared protected rather than r subclass of the defining class has the feature. private in Circle is accessible in ColoredCircle. ! Suppose that a protected instance variable f is public class Circle extends ClosedFigure { defined in class p1.Parent: protected int r; package p1; … public class Parent { } public class ColoredCircle extends Circle { protected int f; private Color c; … … public boolean equals (Object obj) { } return (obj instanceof ColoredCircle) && ! The instances of Child and Grandchild inherit this.r == ((ColoredCircle)obj).r && (and can access) the instance variable f. this.c.equals(((ColoredCircle)obj).c); } ! Also accessible anywhere in the package p1 … 75 76 }

Package private features Package private features …

! A package private feature is used in situations in which we want to permit a closely related class that is not a subclass to have access to a feature. ! Explorer has a command move(), and in the process of executing this command an Explorer might leave one Room and ! For example, consider the classes Explorer and Room from enter another. the maze game. ! If the system is to remain consistent, the command move() must ! Suppose that the Explorer must know which room it is in, inform a Room that the Explorer is entering or leaving. and the Room must know its contents:

77 78 Package private features … Package private features …

! We equip a Room with methods for adding and removing an ! How should we label these methods? Explorer: ! We can’t declare them private, because they must be invoked void add (Explorer e) from the class Explorer. " The specified Explorer has entered this Room, and ! We don’t want to make them public, because they should only should be added to the contents of this Room. Should be invoked by an Explorer when he leaves or enters the Room. only be invoked by an Explorer when it enters this If they are invoked from anywhere else, we could easily end up Room. with inconsistencies in the system. void remove (Explorer e) ! A possibility is to make them package private (or restricted). " The specified Explorer has left this Room, and should ! If a feature is not declared public, protected, or private, it is be removed from the contents of this Room. Should by default package private. only be invoked by an Explorer when it leaves this Room.

79 80

Package private features … Package private features …

! A package private feature is accessible anywhere in the package ! The classes Explorer and Room are very closely related (tightly containing the class in which the feature is defined. coupled). ! It is also inherited by subclasses that are in that package. ! Not only does each depend on the other, but each depends on the implementation of the other. ! Essentially, a package private feature looks like a public feature inside the package, and like a private feature outside the package. ! Like private features, package private features are part of a class’s implementation and not part of the specification that the ! Therefore if the Room features add() and remove() are package class presents to its clients. private, and if Room and Explorer are in the same package, then an Explorer can invoke the features.

81 82

Package private features … Scoping rules

! The rules regarding feature access are part of the language scoping rules. ! As a general guideline, class coupling should be minimized. ! An identifier may occur many times in a program in many different ! Effects of change should be localize. contexts. ! Access to protected features should only occur in descendants of ! An identifier can be introduced as the name of a variable in a variable the defining class. definition or parameter specification, or as the name of a method in a ! The strength of the design is improved if instance variables are method definition. kept private and access is controlled through public (or protected) ! Such an occurrence is referred to as a defining or naming commands and queries. occurrence of the identifier. ! The following are defining occurrences of the identifiers takeThat(), hitStrength, count, and temp: public void takeThat (int hitStrength) private int count; int temp;

83 84 Scoping rules … Scoping rules …

! A defining occurrence establishes the identifier as the name of ! The scope of a variable is the range of statements in which the some entity. variable is visible. ! Other occurrences, such as occurrences of an identifier in an ! A variable is visible in a statement if it can be referenced in that expression, are called applied occurrences. statement. ! An applied occurrence is simply the use of an identifier to refer to ! A variable is local to a program unit or block if it is defined there the thing it names. (i.e., its defining occurrence is there). ! For example, both occurrences of the identifier count and the ! Nonlocal variables are those that are visible within the program unit occurrences of room, monster, and location() are applied or block but are not defined there. occurrences: ! Scoping rules are used to determine access to nonlocal variables. count = count + 1; ! Mapping applied occurrences of identifiers to defining this.room = monster.location(); occurrences

85 86

Scoping rules … Scoping rules …

! There are two fundamental approaches to scoping: ! Instance variables are still visible throughout the class (with the prefix ) even if the variable is redefined within some local ! static scoping this scope: ! dynamic scoping public class Counter { ! Java uses static scoping. private int count; ! Instance variables are visible throughout the class: public Counter (int count) { public class Counter { this.count = count; private int count; } public void increment () { public void increment () { count = count + 1; count = count + 1; } } … … } 87 88 }

Scoping rules … Scoping rules …

! Blocks (i.e., curly braces) define a local scope: ! Examples of scoping: public class Score { private int[] score; … public double average () { int total; for (int i = 0; i < score.length; ++i) { total = total + score[i]; } return (double)total / (double)score.length; } … } 89 90 Scoping rules … Scoping rules …

! Examples of scoping: ! Examples of scoping:

91 92

Scoping rules … Scoping rules …

! Note that the scope of variables that are defined with a for- ! Examples of scoping: statement is restricted to that for-statement: With the exception of

for (int i = 0; i < a.length, ++i) { instance variables, … redefinitions cannot } be made. // i is no longer available here X X ! The for-statement initialization is considered part of the block.

93 94