Binding

advertisement
CompSci 230 S2 2015
Software Design and Construction
Packages & Binding
Agenda & Reading

Topics:





Packages
Access Modifiers
Static & Dynamic Binding
Casting
Reading

The Java Tutorial




2
Creating and Using Packages
Controlling Access to Members of a Class
Overriding and Hiding Methods
Hiding Fields
06
Packages

Definition: A package is a grouping of related types providing
access protection and name space management.


Purpose: “To make types easier to find and use, to avoid naming
conflicts, and to control access, programmers bundle groups of
related types into packages.”



Conceptually you can think of packages as being similar to different
folders on your computer.
Note that types refers to classes, interfaces …
Examples:




3
A package is a namespace that organizes a set of related classes and
interfaces.”
java.io — file operations
java.lang — basic language functionality and fundamental types
java.util — collection data structure classes
java.awt — basic hierarchy of packages for native GUI components
06
Creating a Package

“To create a package, you



choose a name for the package (folder) and
put a package statement with that name at the top of every source
file that contains the types that you want to include in the package.
Rules:

package X;
There can be only one package statement in each source file, and
must be the first line in the source file.


If you put multiple types in a single source file, only one can be public, and
it must have the same name as the source file.
You can include non-public types in the same file as a public type
This rule makes it easy for the class loader, and the human
programmer, to find the definition for a public type.
4
06
One public type per file!

“If you put multiple types in a single source file, only one can be public,
and it must have the same name as the source file.

For example, you can




“You can include non-public types in the same file as a public type




(this is strongly discouraged, unless the non-public types are small and closely
related to the public type),
but only the public type will be accessible from outside of the package.
All the top-level, non-public types will be package private.”
This rule makes it easy for the class loader, and the human programmer,
to find the definition for a public type.


5
define public class Circle in the file Circle.java,
define public interface Draggable in the file Draggable.java,
define public enum Day in the file Day.java, and so forth.
The name of a package determines the directory in which the files of this
package should be stored.
The name of a public type determines the name of the file in which the
type’s definition must be found.”
06
The default package

“If you do not use a package statement, your type ends up in
an unnamed package.


6
Generally speaking, an unnamed package is only for small or
temporary applications or when you are just beginning the
development process.
Otherwise, classes and interfaces belong in named packages.”
06
Package naming conflicts

“With programmers worldwide writing classes and interfaces
using the Java programming language,



The fully qualified name of each Rectangle class includes
the package name.


7
it is likely that many programmers will use the same name for
different types.
The compiler allows both classes to have the same name if they are
in different packages.
That is, the fully qualified name of the Rectangle class in the
graphics package is graphics.Rectangle, and
the fully qualified name of the Rectangle class in the java.awt
package is java.awt.Rectangle.
06
External references

To use a public package member from outside its package,
you must do one of the following:



The fully qualified name for class C in package p is p.C
To import class C from package p, you write import p.C
To import an entire package p, you write import p.*
package p1;
public class Protection {
int n_default = 1;
public int n_public = 2;
protected int n_protected = 3;
private int n_private = 4;
}
public class Class1 {
public static void main(String[] args) {
p1.Protection c = new p1.Protection();
}
}
8
06
Access Modifiers

Classes, and their fields and methods have access levels to specify
how they can be used by other objects during execution



A private field or method is accessible only to the class in which it is
defined.
A protected field or method is accessible to the class itself, its subclasses,
and classes in the same package.
A public field or method is accessible to any class of any parentage in any
package
Private
Protected
Public
Default
Class itself
YES
YES
YES
YES
Other Subclasses within a package
No
YES
YES
YES
Other classes within a package
No
YES
YES
YES
Other subclasses outside this package
No
YES
YES
No
Other classes outside this package
No
No
YES
No
9
06
Example: subclasses within a package
package p1;
public class Protection {
int n_default = 1;
public int n_public = 2;
protected int n_protected = 3;
private int n_private = 4;
}
p2
OtherPackage
P2Derived
p1
Protection
Derived
SamePackage
Within a package
package p1;
public class Derived extends Protection {
public static void main(String[] args) {
Derived b = new Derived();
System.out.println("n_default=" + b.n_default);
System.out.println("n_public=" + b.n_public);
System.out.println("n_protected=" + b.n_protected);
// System.out.println("n_private" + b.n_private);
}
}
C:/06/access>
javac p1/*.java
java p1.Derived
No access to
Private variable
n_default=1
n_public=2
n_protected=3
Example: p1/Derived.java
10
06
Example: Other classes within a package
package p1;
public class Protection {
int n_default = 1;
public int n_public = 2;
protected int n_protected = 3;
private int n_private = 4;
}
p2
OtherPackage
P2Derived
p1
Protection
SamePackage
Derived
With a package
n_default=1
n_public=2
n_protected=3
package p1;
public class SamePackage {
public static void main(String[] args) {
Protection b = new Protection();
System.out.println("n_default=" + b.n_default);
System.out.println("n_public=" + b.n_public);
System.out.println("n_protected=" + b.n_protected); No access to
// System.out.println("n_private" + b.n_private);
Private variable
}
}
Example: p1/SamePackage.java
11
C:/06/access>
javac p1/*.java
java p1.SamePackage
06
Example: subclasses outside this package
package p1;
public class Protection {
int n_default = 1;
public int n_public = 2;
protected int n_protected = 3;
private int n_private = 4;
}
p2
OtherPackage
P2Derived
Different packages
Protection
Derived
p1
SamePackage
n_public=2
n_protected=3
package p2;
public class P2Derived extends p1.Protection {
No access to the
public static void main(String[] args) {
default variable
P2Derived b = new P2Derived();
//System.out.println("n_default=" + b.n_default);
System.out.println("n_public=" + b.n_public);
System.out.println("n_protected" + b.n_protected); No access to
//System.out.println("n_private" + b.n_private); Private variable
}
}
C:/06/access>
javac p1/*.java
javac p2/*.java
java p2.P2Derived
Example: p2/P2Derived.java
12
06
Example: Other classes outside this
package
package p1;
public class Protection {
int n_default = 1;
public int n_public = 2;
protected int n_protected = 3;
private int n_private = 4;
}
p2
OtherPackage
P2Derived
Different packages
Protection
Derived
p1
SamePackage
n_public=2
package p2;
No access to
public class OtherPackage {
- Default
public static void main(String[] args) {
- protected
p1.Protection b = new p1.Protection();
- private
// System.out.println("n_default=" + b.n_default);
System.out.println("n_public=" + b.n_public);
// System.out.println("n_protected" + b.n_protected);
// System.out.println("n_private" + b.n_private);
}
}
C:/06/access>
javac p1/*.java
javac p2/*.java
java p2.OtherPackage
Example: p2/OtherPackage.java
13
06
Statically or Dynamically typed


Programming languages generally offer some sort of type
system, and can be described as being either statically typed
or dynamically typed
With a statically typed language, compile-time checks are
carried out to determine whether variable usage is valid
Java
int x = 10;
x = "Hello";

In a dynamically typed language, variables are not associated
with a type and are simply names that can be assigned
arbitrary values Python
x = 10;
x = "Hello";
14
06
Java - statically typed language

Every variable name is bound both


to a static type (static type at compile time, by means of a data
declaration) and
static
dynamic
type
to an object (dynamic type) or null
type



the classes of object to which the variable can refer
the message that can be sent using the variable
Restrictions are checked at compile-time


15
Ball b1 = new Ball(...);
Ball b2 = null;
The type imposes restrictions on how a variable can be used. The
type restricts:


The binding to an object is optional.
The compiler will not issue code if it detects a violation.
Java is a “type-safe” language: its compile-time checking restricts the
amount of damage that can be done by careless or malicious
programmers.
06
Static Typing Restrictions

A reference variable of static type T can refer to an instance
of class T or to an instance of any of T’s subclasses



16
In other words, an instance of class T can always be substituted for
an instance of any subclass of T
Through a reference variable of static type T, the set of
messages that can be sent using that variable are the methods
defined by class T and its superclasses
A variable’s static type is fixed at compile time but its dynamic
type may vary at run-time.
06
Example: instance_var/Derived.java
Static Binding: Instance Variables
class Base {
public int x = 10;
}
public class Derived extends Base {
public int y = 20;
}
instance variable x
in Base
//Case 1:
Base b1 = new Base();
System.out.println("b1.x=" + b1.x);
Base b1->
x=10
From
superclass
Derived b2-> x=10
//Case 2:
Derived b2 = new Derived();
System.out.println("b2.x=" + b2.x);
System.out.println("b2.y=" + b2.y);
instance variable x : inherited from Base
y=20
instance variable y in Derived
b3 is declared as type Base, static type
= base; dynamic type = Derived
//Case 3:
Base b3 = new Derived();
System.out.println("b3.x=" + b3.x);
//System.out.println("b3.y=" + b3.y);

Base b3-> x=10
There is no y declared in
Base class -> compile error!
y=20
Note:

17
instance variable x : inherited from Base,
Access to fields is governed by the form of the reference
06
Example: shadow/Derived.java
Static Binding – Hiding a Field
Within a class, a field that has the same name as a field in the
superclass hides the superclass's field

class Base2 {
public int x = 10;
}
instance variable x
in Base
//Case 1:
Base2 b1 = new Base2();
System.out.println("b1.x=" + b1.x);
public class Derived2 extends Base2 {
public int x = 20;
}
Base b1->
x=10
Derived b2-> x=10
//Case 2:
instance variable x from Derived (20)
Derived2 b2 = new Derived2();
System.out.println("b2.x=" + b2.x);
b3 is declared as
type Base
instance variable x from Base, (10)
//Case 3:
Base2 b3 = new Derived2();
System.out.println("b3.x=" + b3.x);
x=20
Base b3-> x=10
x=20
Note:

18
Access to fields is governed by the form of the reference
06
Get the hiding values


Within the subclass, the field in the superclass cannot be
referenced by its simple name
To "unshadow" it by referring to super.x
method In the
public class Derived extends Base {
subclass
...
public void method1() {
System.out.println("x from Derived:" + x);
System.out.println("x from superclass: " + super.x);
...

Note:




19
this.x access the field name x, defined in the child class
super.x access the field name x, defined in a parent class
super.super.x is not valid
x was not specified as private.
06
Example: static_var/Derived.java
Static Binding - Static Variables
class Base {
public static int x;
public Base() {
x++;
}
}
public class Derived extends Base {
public static int y;
public Derived() {
y++;
}
}
class variables:
one copy only
//Case 1
Base b1 = new Base();
System.out.println("Base.x=" + Base.x);
System.out.println("Derived.y=" + Derived.y);
1
0
class variable x : inherited
//Case 2
from Base
Derived b2 = new Derived();
System.out.println("Base.x=" + Base.x);
System.out.println("Derived.x=" + Derived.x);
System.out.println("Derived.y=" + Derived.y);
//case 3
Base b3 = new Derived();
System.out.println("Derived.x=" + Derived.x);
System.out.println("Derived.y=" + Derived.y);
Note:



20
2
2
1
3
2
Base: x= 0->1
Derived: y= 0
b1
Base: x= 0->1->2
Derived: y= 0 ->1
b1
b2
Base: x= 0->1->2->3
Derived: y= 0 ->1->2
b1
b2
b3
Access to fields is governed by the form of the reference
One copy only, all instances of the class share the same static variable
Class variable can be accessed before an object of a class is created, and without reference to a
particular object
06
Example: static_method/Derived.java
public class Derived extends Base {
public static int y=2;
Static Methods
class Base {
public static int x=1;
public static int getY() {
return y;
}
public static int getX() {
return x;
}
public static int getX() {
return 10;
}
}
}
Base b1 = new Base();
Base b2 = new Derived();
Invoke getX in Base
System.out.println("b1.getX()=" + b1.getX());
1
1
Invoke getX in Base
No Overriding for static method
System.out.println("b2.getX()=" + b2.getX());
//System.out.println("b2.getY()=" + b2.getY());
Compile error
No getY in Base
System.out.println("Derived.x=" + Derived.getX());
System.out.println("Derived.y=" + Derived.getY());
Invoke getX and getY
in Derived
10
2
Note:


21
Static methods can only invoke other static methods and access other static variables
Only the non-static methods of a class can be overridden
06
Dynamic Binding
Dynamic Binding refers to the case where compiler is not able to
resolve the call and the binding is done at runtime only.
A call of that method (method1) can only be resolved at runtime as the
compiler can't be sure of what type of object this reference would be
pointing to at runtime.



The search for a method begins with the dynamic class.

If this class doesn’t implement the method (i.e. it doesn’t introduce or override the
method), the search progresses to it’s superclass. This process is repeated up the
hierarchy until the method is found.
Derived b2 = new Derived();
Base b3 = new Derived();
Dynamic class
b2.f();
b2.g();
b2.h();
22
f() in Derived, f() in Base?
Invoke f() in Base
g() in Derived?
Invoke g() in Derived
h() in Derived?
Invoke h() in Derived
b3.f();
b3.g();
b3.h();
f() in Base?
Invoke f() in Base
g() in Base?
Invoke g() in Derived
h() in Base?
Compile time error
class Base {
public void f() { ... }
public void g{} { ... }
}
public class Derived extends Base {
public void g{} { ... }
public void h() { ... }
}
06
Casting
Casting an object to a different type will permit access to fields
shadowed by the type of the original object
Casting an object to a different type will have NO effect on which
method is invoked in response to a given message. Once overridden,
methods remain overridden
To cast, just precede a value with the parenthesised name of the desired
type
A ClassCastException is thrown if the type cast is incompatible with the
type of object to be pointed to.
To check that a potential cast is safe, the instanceof operator should be
used







The instanceof operator Can be used to determine the type of an object
Returns true if <obj> can be assigned into a reference of type <Class name>.
That is, instanceof checks if the <obj> is-an instance of the specified class,
provided obj is not null.
Derived d = (Derived) b3;
Base b4 = (Base) b4;
23
<obj> instanceof <Class name>
06
Example: casting/Primitive.java
Wider type
Primitive Types

Widening conversions


Wider assignment
Wider Casting

Casting
needed
Casting a value to a wider value is always permitted but never required. However,
explicitly casting can make your code more readable
double d = 4.9;
int i = 10;
double d1, d2;
Assignment conversion
d1 = 10.0
d1 = i;
d2 = (double) i;

Narrowing conversion


Narrow assignment – Compile-time error
Narrow Casting – Loss of information

You must use an explicit cast to convert a value in a large type to a smaller type,
or else converting that value might result in a loss of precision.
double d = 4.9;
int i = 10;
int i1, i2;
24
Casting conversion
(optional)
d2 = 10.0
//i1 = d;
i2 = (int) d;
Assignment conversion
Compile-time error
Narrow Casting: i2=4
NOTE: Everything beyond the decimal point will be truncated
06
Example: casting/CastObject.java
Object Types
Widening conversions



Wider object reference assignment conversion
Wider object reference casting (optional)
Base b = new Base();
Derived d = new Derived();
Base b1, b2;
System.out.println(d.y);

Note:



25
Wider type
Base
Derived
Assignment conversion - OK
However, no access to fields in Derived
b1 = d;
//System.out.println(b1.y);
Widening Casting conversion - OK
However, no access to fields in Derived
b2 = (Base) d;
//System.out.println(b2.y);
Reference conversion, like primitive conversion, takes place at compile time,
because the compiler has all the information it needs to determine whether
the conversion is legal
Inheritance relation is an “is a” relation; the parent object is more general
than child object
The general rule of thumb is that converting to a superclass is permitted
(because super class is wider than sub class)
06
Wider type
Object Types
Person
Example: casting/CastObject.java
Student
Narrowing conversion



Narrow object reference assignment – Compile-time error
Narrow object reference casting –


Compile-time OK,
Run-time?


Like primitive casting: By using a cast, you convince the compiler to let you do a
conversion that otherwise might not be allowed
The run-time check determines whether the class of the object being cast is compatible
with the new type
Base b = new Base();
Derived d = new Derived();
Derived d1, d2, d3;
//d1 = b;
Compile-time error
d2 = (Derived) b;
Base b-> x=10
Compile-time OK, Run-time ERROR
b is an instance of class Base, not Derived
java.lang.ClassCastException: Base
Base d_as_b = new Derived();
d3 = (Derived) d_as_b;
Base d_as_b-> x=10
26
y=20
Compile-time OK, narrow casting,
casting from superclass to subclass
Run-time OK
d_as_b is an instance of Derived
06
Example: Casting/Recover.java
Using Casting

Shadowing

Using type casting, it is possible to recover a hidden member (class variable,
class method, or an instance variable), but not an overridden method (i.e. an
instance method). An overridden method can be recovered only by means of
a super call in derived class
class Base2 {
public int x = 10;
}
public class Derived2 extends Base2 {
public int x = 20;
}
Derived2 d = new Derived2();
Base2 b = new Derived2();
System.out.println( "d.x=" + d.x);
System.out.println( "((Base2)d).x=" + ((Base2)d).x);
Hiding
20
10
System.out.println( "b.x=" + b.x);
System.out.println( "((Derived2)b).x=" + ((Derived2)b).x);
27
Derived2 d-> x=10
x=20
10
20
Base2 b-> x=10
x=20
Hiding
06
Example: TestInstanceOf.java
Instanceof
p
Person p = new Person();
System.out.println(p instanceof Person);
System.out.println(p instanceof Student);
true
false
Person p1 = new Student();
System.out.println(p1 instanceof Person);
System.out.println(p1 instanceof Student);
System.out.println(p1 instanceof Employee);
Student
TertiaryStudent
Employee
CollegeStudent
true
true
false
Person
Student
TertiaryStudent
28
Person
p1
Employee
CollegeStudent
06
Person
Instanceof
Student
TertiaryStudent
ts
TertiaryStudent ts = new TertiaryStudent();
System.out.println(ts instanceof Student);
Employee
CollegeStudent
true
// System.out.println(ts instanceof CollegeStudent);
// System.out.println(ts instanceof Employee);
no instance of TertiaryStudent, or any of its possible subclasses could possibly
be an instance of any subclass of CollegeStudent/Employee
=> Compile-time error
Student s2 = new TertiaryStudent();
System.out.println(s2 instanceof TertiaryStudent);
System.out.println(s2 instanceof CollegeStudent);
//System.out.println(s2 instanceof Employee);
true
false
Person
Student
Employee
s2
TertiaryStudent
CollegeStudent
29
06
Person
Exercise:
Student
TertiaryStudent
Employee
CollegeStudent
At compile-time, checking is carried out to determine whether the cast-type
and the type of the existing reference variable are related through inheritance.
At run time, a check is made to determine whether the object actually pointed
to is compatible with the cast-type.


Compiletime
Runtime
(TertiaryStudent) s1
OK
OK
(TertiaryStudent) s2
OK
OK
(TertiaryStudent) e1
ERROR
(TertiaryStudent) s3
OK
ERROR
(TertiaryStudent) s4
OK
ERROR
(Students) S2
OK
OK
Student s1 = new TertiaryStudent();
TertiaryStudent s2 = new TertiaryStudent();
Employee e1 = new Employee();
Student s3 = new CollegeStudent();
Student s4 = new Student();
30
06
Summary

Object Conversion




Make it possible to reference an object in a different way by assigning it to an
object reference of a different type.
It is handled automatically by the compiler.
The object is NOT converted or changed in any way. Once instantiated, an
object NEVER changes its type (a Cat will always be a Cat). The concept is
similar to the "widening conversions" performed on primitive data types.
Casting




31
Student s = new Student();
Person p = s;
It is needed when the compiler doesn't recognize an automatic conversion.
The concept is similar to the casting of primitive data types to perform a
"narrowing conversion".
Casting does not change the reference or the object being pointed to. It only
changes the compiler’s treatment of the reference
Casting is only legal between objects in the same inheritance hierarchy
You can safely cast from an object to its superclass
06
Overriding, hiding, and overloading
methods


“An instance method in a subclass with the same signature (name,
plus the number and the type of its parameters) and return type as
an instance method in the superclass overrides the superclass's
method.”
“If a subclass defines a class method with the same signature as a
class method in the superclass, the method in the subclass hides the
one in the superclass.

“The distinction between hiding and overriding has important
implications.



“Overloaded methods are differentiated by the number and the
type of the arguments passed into the method.”

32
The version of the overridden method that gets invoked is the one in the
subclass.
The version of the hidden method that gets invoked depends on whether it is
invoked from the superclass or the subclass.”
“The compiler does not consider return type when differentiating
methods, so you cannot declare two methods [in the same class] with the
same signature even if they have a different return type.
06
Download