Object
Oriented Programming (in Java)
Fundamental Concepts
programming = construction of a class
class = a description of a set of objects sharing the same
structure
object = a
state machine (instance of class)
state = a composition of
data
(primitive types)
other
objects (reference types)
behavior = a set of procedures on the
states
package = a set of classes (class library)
encapsulation mechanisms = walls for access,
visibility control of names
package
P
class
m ( ) C
method
P.C.m( )
Class definition (Naming)
class A { v1;
v2; . . . m1(); m2(); . . . }
Class usage
declaration
of variable A a,
aa;
creation
of instance a = new A();
activation
of method a.m();
system
defined operations aa = a;
aa
== a
a instanceof
A
Object: boolean equals(Object obj)
Object clone()
Object interaction:
class A { . . .; B b
= new B(); . . . }
![]()
A a = new A()
·
a creates
b (a has b)
·
a accesses
b
directly: b.x
|
|
indirectly: b.m()
·
a accesses
b and c
b.m(c) --
call by value for primitive types -- call by reference for reference types
b
accesses c.z through
a.f()
a connects
b and c by executing b.m(c) in f()
b requests
c.z by executing c.n()
in m(c)
c grants
c.z by executing return z
in c.n()
|
|
·
a deletes
b (automatic)
garbage
collection
Class Inheritance (Sub-classing, Prefixing):
class A { v1; m1( ) }
class
B extends A { v2 ; m2( ) }
(
B is A )
class
C extends B { v3 ; m3( ) }
(
C is B
and C is A )


A a = new A(); static
and dynamic type of a is A
B b = new B(); static
and dynamic type of b is B
C c = new C(); static
and dynamic type of c is C
a
= b; ok (the dynamic type
of a
is B)
a
= (A) b; ok (safe casting, always
valid)
b
= a; illegal, compiler error
(undefined fields); b.m2() ?
b
= (B) a; ok (unsafe casting) if
the dynamic type of a is B
otherwise,
runtime error
To
be safe: if (a instanceOf B) b = (B) a;
a
= c; ok (the dynamic type
of a
is C)
b
= c; ok (the dynamic type
of b
is C)
class A {
public int x = 1;
public int get(){ return x; }
}
class B extends A {
public int x = 2;
2
public int get(){ return x; }
get()![]()
}
get()
B
public
class CastTest {
1
public static void main(String args[]) {
A a = new A();
B b = new B();
if (
a instanceof B){ //possible
ClassCastException
b
= (B) a;
System.out.println(b.x);
System.out.println(b.get());
}
a =
b;
System.out.println(a.x);
// 1
System.out.println(a.get());
// 2
a =
(A) b;
System.out.println(a.x); // 1
System.out.println(a.get());
// 2
// b = a; compiler error
b =
(B) a;
System.out.println(b.x);
// 2
System.out.println(b.get());
// 2
// b = (A) b; compiler error
}
}
Shadowed Variables (from class C): Static

v m() A
v1 = v2 = v3 = v
((A) this)
v m()
![]()
v v
in class C
B
this.v v in class C
super
super.v v in class B
v m() C
((B) this).v v in class B
this
((A) this).v v in class A
super.super.v illegal
Overriding Methods (from class C): Dynamic
m1 = m2 = m3 = m
a
= new A();
a.m(); same as a.m1()
a.v same as a.v1
b
= new B();
a
= b;
a.m(); m2()
a.v v1
c
= new C();
a
= (A) c;
a.m(); m3()
a.v v1
b
= (B) a compile ok,
possible runtime error
b.m(); m3()
b.v v2
a
= (A) b;
a.m(); m3()
a.v v1
b
= (B) a; compile ok,
runtime ok
b.m(); m3()
b.v v2
Visibility Modifiers
Class Member Accessibility [Table 3-1, page 73]

C’ has access to only public
members of A.
class C’ { A a; a.x
}
C has access to all non-private members of A.
class
C { A a; a.x
a.y a.z }
B’ has access to and inherits public and protected
members of A.
class B’ extends A { A a;
a.x a.y x
y }
B has access to and inherits public, protected and default (package) members of A.
Class B
extends A { A
a; a.x a.y
a.z x y
z }
Abstract Method = interface definition only (pure virtual function)
no implementation (no body part)
Regular Method Declaration
[modifiers] type name
( parameters ) [throws exceptions] { method body }
Abstract Method Declaration
[modifiers] abstract type
name ( parameters ) [throws exceptions]
Abstract Class = a class that contains at least one abstract method
ex.
abstract class
Shape { abstract void draw(); }
class Box extends Shape { . . . void draw(){ draw
this box }; . . . }
class Arrow extends Shape { . . . void draw(){ draw
this arrow }; . . . }
class Graph { . .
.
Shape[]
shapes = new Shape[100];
shapes[0] = new Box( ... ); shapes[1] = new Arrow( ... ); . . .
for ( int i = 0; i < shapes.length; i++
) shapes[i].draw(); . . .
}

Note:
·
A
class may be declared abstract (to prevent instantiation) even if it has no
abstract methods.
·
An
abstract class may have non-abstract methods.
·
If
there is an abstract method, the class must be declared as abstract.
·
An
abstract class cannot be instantiated.
·
If
a subclass of an abstract class does not implement all of the abstract methods
it inherits, that subclass is itself abstract.
Interface = a reference type whose members are constants and
abstract methods
interface I { .
. . m(); . . . }
interface J { .
. . n(); . . . }
class A implements
I, J { . . . m(){ m1
}; . . .; n() { n1 }; .
. . }
class B implements
I, J { . . . m(){ m2
}; . . .; n() { n2 }; .
. . }
I i =
new A();
I ii =
new B();
J j =
new A();
J jj =
new B();
i.m(); execution
of m1 i.n() is illegal
ii.m(); execution
of m2 ii.n() is illegal
j.n(); execution
of n1 j.m() is illegal
jj.n(); execution
of n2 jj.m() is illegal
Notes:
(1) No inheritance of variables.
(2) Interfaces can be extended.
interface K extends
I { p(); }
class C implements
K { . . .; m(){ m3 }; . . .; p(){ p1 }; . . .
}
class D extends
A implements K {
p(){ p2 }; }
K k =
new C();
K kk = new D();
k.m(); execution
of m3
kk.m(); execution
of m1
k.p(); execution
of p1
kk.p(); execution
of p2
(3) No inheritance of method
implementation.
class C
implements K { .
. .; p(){ p1 }; . . . }
No definition of m(){ } causes a
compiler error.
Main Usage Multiple inheritance
Callbacks
Anonymous Class
(JDK1.1) = unnamed
class defined within an expression
where
only one instance of the class is created.
new supertype ( [construction parameter] ) {
classbody }
(supertype = class)
= construct an instance of a class that extends the class
(supertype = interface)
= construct an instance of a class that implements the interface
Note: Since there is no name for the class,
Only one instance, no
constructor, no static field, no modifier, and
instance initializer
(for any class) = constructor with no arguments.
ex. class A { public int[] a;
{ a = new int[10];
for(int I=0; I<10; I++) a[I] = 1;
}
. . .
{
any initialization statement }
. . .
}
Instance
intializers { … } are executed in sequence after the superclass constructor but
before the constructor of the current class.
new supertype ( [construction parameter] )
{ { initializer } classbody }
ex1. Button b1 =
new Button(“Help”) { . . actions
for Help . . }
º
class BH extends Button { . . actions for Help . . }
Button b1 = new
BH(“Help”)
Button
b2 = new Button(“Stop”) { . . actions for Stop . . }
º
class BS extends Button { . . actions for Stop . . }
Button
b2 = new BS(“Stop”)
Ex2. interface A {
int g(); }
class E { A
f() { return new A() { int
g() { return 3; }; }; } }
E e
= new E();
A a
= e.f();
a.g()
== 3 yes
/** * Anonymous
classes can not define static members and can not have * constructors
since they don't have names. They
can override superclass * methods. Defining new non-static members that do
not exist in the * superclass is
allowed, but the new members can not be accessed via * normal means,
since one can not typecast to an anonymous class type * or declare a
variable of an anonymous type. * Erik B. Berry */ package test; class A extends Object{ public int h =
1; public int i =
2; public int e()
{return 10;} public int f()
{return 11;} } public class test { public static
void main(String[] args) { // An
anonymous class extending A. The
two new declarations are legal, but // virtually
useless. Static members are
disallowed by the compiler. A a = new A()
{ public int
i = 3; public int j
= 4; // Produces
Error: Variable k cannot be static in an anonymous class //public
static int k = 5; public int
f(){ return 12; } public int
g(){ return 13; } }; // Prints the
expected 1
System.out.println(a.h); // Prints the
expected 10
System.out.println(a.e()); // Prints 2,
because a is of type A, not the anonymous type (shadowing)
System.out.println(a.i); // Prints 12,
because this is an overridden superclass method // with
dynamic (runtime) binding
System.out.println(a.f()); // Produces
error: method g() not found in class test.A
//System.out.println(a.g()); // Produces
error: variable j not found in class test.A
//System.out.println(a.j); } } /** * Note:
Technically, one could access new members defined by an anonymous * class using
reflection in Java 1.1 or by placing the .method invocation * immediately
after the anonymous class declaration's ending brace. */