Object Oriented Programming in Java Introduction
Object Oriented Programming in Java
Introduction to Computer Science II I Java is Object-Oriented
I Not pure object oriented
Christopher M. Bourke I Differs from other languages in how it achieves and implements OOP [email protected] functionality
I OOP style programming requires practice
Objects in Java Objects in Java
Java is a class-based OOP language
Definition Contrast with proto-type based OOP languages
A class is a construct that is used as a blueprint to create instances of I Example: JavaScript itself. I No classes, only instances (of objects)
I Constructed from nothing (ex-nihilo)
I Objects are concepts; classes are Java’s realization of that concept I Inheritance through cloning of original prototype object
I Classes are a definition of all objects of a specific type (instances) I Interface is build-able, mutable at runtime
I Classes provide an explicit blueprint of its members and their visibility
I Instances of a class must be explicitly created
Objects in Java Objects in JavaI Paradigm: Singly-Rooted Hierarchy Object methods
1 //ignore: 2 protected Object clone(); 3 protected void finalize(); I All classes are subclasses of Object 4 Class getClass(); 5 I Object is a java object, not an OOP object 6 //multithreaded applications: I Makes garbage collection easier 7 public void notify(); 8 public void notifyAll(); I All instances have a type and that type can be determined 9 public void wait(); I Provides a common, universal minimum interface for objects 10 public void wait(long timeout); I Avoids complex lattice relations in other OOP languages: no multiple 11 public void wait(long timeout, int nanos); inheritance 12 13 //important ones: 14 public boolean equals(Object obj); 15 public int hashCode(); 16 public String toString(); Objects in JavaII Declaring Classes Object methods Syntax
I Classes must be defined in file of the same name ( .java )
I equals returns true/false whether or not obj is equal to this I Class names should be upper-camel case, singular form
I Default behavior: uses reference comparison 1 package foo.bar; I hashCode returns an integer hash of this object 2 3 /* imports here */ I Default behavior: typically the memory address of the object 4 I toString provides a human readable representation of the object 5 public class MyClass{ I Default behavior: qualified class name plus JVM memory address 6 7 /* static field declarations */ 8 /* member field declarations */ 9 /* member method declarations */ 10 11 }
Object Life CycleI Object Life CycleII
Instantiation Persistence I New objects created using the new operator: Student s= new Student(); I Instances persist until they are out of scope, no longer referenced, etc.
I All classes have a default constructor if no constructor is defined I Can be serialized (written to disk, database, or transmitted over a
I If non-default constructor defined, default constructor is not provided network)
I Can have multiple constructors I Serializable interface, using writeObject(java.io.ObjectOutputStream out) I Good practice: constructor variants should call other constructors when appropriate readObject(java.io.ObjectInputStream in)
I Example: this(...)
I If calling another constructor: must be done first!
Object Life CycleIII Inner Classes
Destruction
I Can set a reference to null: Integer a= 10;a= null; I Java allows you to declare a class within a class I When no reference to an object exists, eligible for garbage collection I Visibility: allowed to be public, private, protected
I No guarantee of when it gets destroyed I Static or not
I No destructors in Java I Static fields must be final
I Cannot rely on finalize() I No static methods allowed unless inner class is static
I Cannot rely on System.gc() I Example?
I Good practice: Do all cleanup manually in a finally block Anonymous ClassesI Anonymous ClassesII
1 List
Abstract Classes Abstraction
I A class can be made abstract I All public methods and fields available to client code
I Such a class cannot be instantiated I Static methods/fields available without an instance
I Instances must be created from non-abstract subclasses I Interfaces (revisited)
I May contain abstract and non-abstract methods I Abstract classes (revisited) I final keyword: I Non-abstract methods provide a “default” behavior for subclasses I A final class cannot be subclassed Need to provide a default? Use an abstract class! Don’t or don’t want to? I A final method cannot be overridden in a subclass Use an interface! I A final field cannot be reassigned (does not imply immutable)
InterfacesI InterfacesII
An interface is an abstract type that defines method signatures that Syntax: must be implemented by a class 1 public interface InterfaceName{ 2 return-type methodName(); I Methods are always public (or default) and abstract 3 ... I May also define ( final static ) constants 4 }
I No default implementation can be defined 1 public class Foo implements InterfaceA, InterfaceB{ I A class can implements multiple interfaces 2 ... 3 } I Allows us to simulate multiple inheritance without being locked into a hierarchy Interface Example Advantages of an interfaceI
1 public interface Gradeable{ 2 public double getScore(); 3 public String getLabel(); 4 } Interfaces provide a means to: 5 ... 6 public class Exam implements Gradeable{ I Simulate multiple inheritance 7 ... 8 public double getScore(){ I Provide interface (an is-a relationship) without locking you into a 9 return this.numPoints/ this.totalPoints; hierarchy 10 } 11 public String getLabel(){ 12 return "Exam: "+ this.examNumber; 13 } 14 }
Advantages of an interfaceII Other interface items
Example:
I Collections framework: java.util.List , java.util.Set Person Payable I Note: an interface can extend other interfaces (sub/super interface)
I Example: java.util.List extends java.util.Collection
Intern Employee Supplier I Though not a class, still provides the is-a relation
I You can refer to an implementing class as its interface:
Hourly Salaried 1 List l= null; 2 ArrayList al= new ArrayList(); Figure : Inheritance through interfaces 3 l= al;
Encapsulation InheritanceI
I Encapsulation achieved through declaring member fields, methods
I Visibility provides protection I Java supports inheritance through subclassing I Common idiom: Mutators and Accessors (getters and setters) I Syntax: extends keyword public class MySubClass extends MySuperClass{ ...} Modifier Class Package Subclass World I Superclass methods and fields are inherited (provided they are not public Y Y Y Y private) protected Y Y Y N I Subclasses may override superclass methods none (default) Y Y N N private Y N N N I Good practice: use the @Override annotation
Table : Java Access Levels InheritanceII Composition
I Subclass methods can access super class methods and fields using I Java supports composition through the same mechanism as super encapsulation I Can be a pure substitution: no new methods introduced in a I A Java class can have classes as members subclass, or I What’s responsible for constructing it? I New methods may be declared in a subclass I May be completely internal, may be provided, etc. I Preventing subclassing: final (examples: java.lang.Integer , libraries) 1 public class Foo{ I Recall: all methods in Java are virtual by default 2 private Integer a; 3 private Graph g; I Note: a pure virtual method in java is an abstract method 4 protected List
Polymorphism Automatic Type CastingI
I Many mechanisms for polymorphism
I Many different types of polymorphism supported I Numerical operators support mixed types ( int, double , etc.) I Some types not supported: I Simpler types are up-casted to compatible types and (may be) I Operator overloading not allowed 1 downcasted in the final result I Behavioral polymorphism I A form of coercion I Polymorphic behavior not always apparent
1A form is enforced in that super() must be called first in a constructor, ensuring an is-a relationship before anything else can be done
Automatic Type CastingII AutoboxingI
1 inta= 10; 2 doubleb= 20.5,c= 10.5,f; I Autoboxing/unboxing: mixing primitive numeric types with Java 3 intd,e; wrapper classes 4 //d = a + b; <- compile error. 5 // requires explicit cast to int, works in C! I As needed, compiler replaces expressions with value methods 6 f=a+b; I May result in runtime NullPointerException 7 e=(int)(b+c); 8 System.out.println("f = "+f); I Need to be careful when mixing types with comparison operators 9 System.out.println("e = "+e); I Form of coercion AutoboxingII AutoboxingIII
From the Java documentation: So when should you use autoboxing and unboxing? Use them only when there is an impedance mismatch between reference 1 Integer a= new Integer(10); types and primitives, for example, when you have to put 2 Double pi= new Double(3.14); numerical values into a collection. It is not appropriate to use 3 intb= 20; autoboxing and unboxing for scientific computing, or other 4 doublec=a+b+ pi; 5 //becomes: performance-sensitive numerical code. An Integer is not a 6 //double c = a.doubleValue() + b + pi.doubleValue(); substitute for an int ; autoboxing and unboxing blur the distinction between primitive types and reference types, but they do not eliminate it.
Or: when null values are needed to distinguish between missing/invalid/unknown data (tri-valued logic)
String CastingI String CastingII
How this works:
I Rather than dynamic dispatch, Java replaces string concatenation I Plus operator ( + ) is overloaded code
I Could mean addition or (string) concatenation I For efficiency, compiler replaces + with StringBuilder instances
I Can mix Strings and any other Object I StringBuilder uses (overloaded) static String.valueOf() method Object public String toString() I Since has a method I Converts null instances to the string "null" , otherwise calls object’s toString() method
I A form of operator/method overloading and coercion
String CastingIII String CastingIV
Example 2: Example 1: 1 Integer a= null; 2 System.out.println("a = "+a); 1 String a= "hello "+ "world "+ "!"; 3 a= new Integer(10); 2 //would actually become: 4 System.out.println("a = "+a); 3 String a= new StringBuilder().append("hello ") 5 a= null; 4 .append("world ").append("!").toString(); 6 System.out.println("a = "+String.valueOf(a)); 7 System.out.println("a = "+a.toString()); String CastingV Upcasting
I Upcasting is when an instance is treated as its superclass
I Form of subtype polymorphism Result: 1 public class Dog extends Animal{ 1 a= null 2 .... 2 a= 10 3 3 a= null 4 public void doSomething(Animal a){ 4 Exception in thread "..." java.lang.NullPointerException 5 //a is treated as an animal here 6 ... 7 8 Dog d= new Dog(); 9 doSomething(d); 10 //or: 11 Animal a=d;
DowncastingI DowncastingII
I Downcasting works in the opposite direction
I An instance is explicitly cast to a subclass: 1 Animal a= ... Animal a; ... 2 ... Dog d=(Dog)a; 3 Dog d= null; 4 if(a instanceof Dog){ I A subclass always has an is-a relationship 5 d=(Dog)a; I Does not work in this case: may not be-a! 6 } I May be problematic if a is not a Dog : ClassCastException
I Useful tool: instanceof
I Useful tool: getClass() method, .class static element
DowncastingIII Method OverloadingI
1 Integer c= 10; 2 if(c instanceof java.lang.Number){ I A method’s signature depends on its name and parameters 3 System.out.println("Its a numeric: "+c.getClass()); I Java allows you to overload methods; that is: 4 } 5 if(c.getClass() == java.lang.Integer.class){ I Define methods with the same names but different (number or type) 6 ... parameters 7 } I Compiler uses dynamic dispatch to call the appropriate method 8 if(c.getClass().equals(java.lang.Integer.class)){ 9 ... I However: cannot define methods with same name, parameters, but 10 } different (covariant) return types (more later) Method OverloadingII Method OverridingI
1 public void foo(){} I In a subclass (non-private, non-final) methods can be overridden 2 public int foo(Integer a){return0;} I Implementation can be changed 3 public int foo(Integer a, Double b){return0;} I Method signature and return type cannot change 4 public String foo(Double a){return "0.0";} 5 //not allowed: I Visibility can be increased but not restricted further 6 //public double foo(Double a) {return 0.0;} I Good practice: use the @Override annotation
I Still have access to the superclass’s method ( super.methodName() )
Method OverridingII Method OverridingIII
1 public class Dog extends Animal{ 1 public class Animal{ 2 ... 2 ... 3 @Override 3 protected void eat(){ 4 public void eat(){ 4 System.out.println("Eating..."); 5 System.out.println("Eating a milkbone..."); 5 } 6 } 6 ... 7 ... 7 } 8 }
Method OverridingI Covariant Return TypesI toString method
1 public class Student{ 2 private int id; I In general, an overridden method must have the same return type 3 private String firstName; 4 private String lastName; I Since Java 1.5: allowed to return a covariant type 5 ... I Return type can be changed to another type as long as the new 6 public String toString(){ return type has an is-a relation to the original 7 return this.lastName+","+ this.firstName+ 8 " ("+ this.id+ ")"; I Cannot be an arbitrary type 9 } Covariant Return TypesII Parameterized PolymorphismI
1 public classA{ 2 public Animal getOrganism(){ I Generics introduced in Java 1.5 3 ... I Named parameter syntax:
Parameterized PolymorphismII Parameterized PolymorphismIII
1 //no compile error, no run time error 1 ArrayList
Parameterized PolymorphismIV Parameterized PolymorphismV
1 //unparamterized list: 1 public static
I Upper bound: – matches T and any subtype of T
I Lower bound: – matches T and any super type of T I Revisit the getMax example: unable to establish a criterion for comparison I Named upper bounded:
Bounded PolymorphismIII Bounded PolymorphismIV
I Cannot specify upper and lower bound on the same type (for either 1 public static
Bounded PolymorphismV More on Bounded ParameterizationI
Using the Comparable interface:
1 public static
The only thing you know about the stuff is that they are Object s: Same, but the parameter type is named and it can now be used:
1 public static void foo(List stuff){ 1 public static
More on Bounded ParameterizationIV More on Bounded ParameterizationV
By providing a bound we know more about the type T : its a subclass of But we didn’t really use the type T , so we could have instead used a BankAccount and therefore is-a BankAccount wildcard, but still provide a bound on the argument, guaranteeing a minimal interface. 1 public static
More on Bounded ParameterizationVI More on Bounded ParameterizationVII
Alternatively, we can use both named parameters and wildcards to make However, if we do need to reference the type in the method, then we must our code a bit more general (and thus flexible to those using it). Here we use a named parameter. have the same advantages as before, but now the list can be generalized 1 public static
More:
I Generics introduced in Java 1.5 I Good post: http://stackoverflow.com/questions/3486689/ java-bounded-wildcards-or-bounded-type-parameter I But Collections framework introduced in Java 1.2 I Object I PECS (Producer extends, Consumer super) principle: Old interfaces (and many libraries) involve the type http://stackoverflow.com/questions/2723397/ I Example: List.add(Object obj) java-generics-what-is-pecs I Upcasting eliminates any type-specific information
Type Erasure & Raw TypesII Type Erasure & Raw TypesIII
I Java designers made a choice: backwards compatibility over strict 1 List
Open Recursion Copy ConstructorsI
I Copy Constructors are preferred to using Object.clone() or the I Inside classes, we need a way to reference the object itself Cloneable interface; more info:
I Open recursion (recursive because the object is referencing itself) I http://www.artima.com/intv/bloch13.html I http://www.javapractices.com/topic/TopicAction.do?Id=71 I this. allows you to access member methods/variables I http://adtmag.com/articles/2000/01/18/ I this(...) allows you to call another constructor effective-javaeffective-cloning.aspx
I super. allows you to access member methods/variables of the I All state should be copied superclass I Immutable objects can be reference-copied I super(...) allows you to call a constructor of the superclass I Mutable objects should be deep copied
I Useful methods: Arrays.copyOf(...) DemonstrationI
Design a Student object and a Course object and illustrate usage of:
I A copy constructor and deep vs. shallow copy
I Bi-directional association (roster and/or schedule)
I Potential pitfalls of bi-directional association
I Bi-directional association through an intermediate class