MSc Revision Notes - Object Oriented Programming
Exam topics
Main topics
- Generics (Paper 3)
- Aspect Oriented Programming (Paper 3)
- Threads (Paper 4)
Other topics
- Polymorphism
- Exceptions
- Inner classes
- Interfaces / Abstract classes
- Design patterns
- Reflection
Generics
Useful Links
Notes
Generics enable compile-time checking of the type safety of operations on a collection.
- The compiler verifies any operation that adds an object to a collection.
- Removes the need to cast objects returned from a collection.
- No class relationship exists between instances of generic types (But see next point). Eg.
1 List<String> ss = new ArrayList<String>(1); 2 List<Object> os = ss; // WRONG! Causes compile-time error!
- Define a generic type like a regular type, but with a type parameter declaration attached.
1 interface Comparable<E> { 2 int compareTo(E other); 3 } 4
- Instantiate a generic type by providing one type argument per type parameter that was declared for the generic type.
- Wildcard instantiation
Unbounded: eg: reverse(List<?> list) means the reverse() method can accept a List of any type. This is not the same as: reverse(List<Object> list) as this would only accept Lists of type Object.
Bounded
Lower bound: List<? super Number> means the List must contain either Number objects or any superclass of Number.
Upper bound: List<? extends Number> means the List must contain either Number objects or any subclass of Number.
- With wildcard (unknown) types we cannot write into the collection, only read from it. You cannot just shove Objects into a collection of unknown type.
- Type variables may be bounded as well. Eg. The compiler will enforce the constraint that a Library can only contain Media objects (and not, say, Numbers).
1 public class Library<T extends Media> { 2 ... 3 }
Generic methods are a way to deal with the problem of inserting objects into collections that use unknown types. Here is an example of what not to do from the Sun tutorial:
Here is how to accomplish it using a generic method:1 static void fromArrayToCollection(Object[] a, Collection<?> c) { 2 for (Object o : a) { 3 c.add(o); // Compile time error 4 }
We can call this method with any kind of collection whose element type is a supertype of the element type of the array.1 static <T> void fromArrayToCollection(T[] a, Collection<T> c) { 2 for (T o : a) { 3 c.add(o); // Correct 4 } 5 }
The component type of an array object may not be a type variable or a parameterised type unless it is an unbounded wildcard type.
- Instantiations of a generic type share the same runtime type because of type erasure.
Threads
Useful Links
Notes
Two ways to create a thread: subclassing Thread or implementing Runnable
Create a thread by subclassing the Thread class and overriding its empty run method. The run method gives a thread something to do. Eg,
The following code will then create a thread and start it running1 public class SimpleThread extends Thread { 2 public SimpleThread(String str) { 3 super(str); 4 } 5 6 public void run() { 7 for (int i = 0; i < 10; i++) { 8 System.out.println(i + " " + getName()); 9 try { 10 sleep((long) (Math.random() * 1000)); 11 } catch (InterruptedException e) {} 12 } 13 System.out.println("Done!" + " " + getName()); 14 } 15 }
1 new SimpleThread().start();Declare a class that implements the Runnable interface. That class then implements the run method. An instance of this class is then allocated to a thread. Eg,
The following code will then create a thread and start it running:1 class Foo implements Runnable { 2 public Foo() { 3 // Whatever... 4 } 5 public void run() { 6 // Do something... 7 } 8 }
1 Foo myFoo = new Foo(); 2 new Thread(myFoo).start();
If your class must subclass another class then you should use the Runnable interface.
- Java uses simple priority-based scheduling.
Get and set a thread's priority with getPriority() and setPriority
A thread may give up its right to execute by calling yield()
- If threads share a common resource they must be synchronized. Whenever control enters a synchronized method, the thread that called the method locks the object. Other threads cannot call any synchronized methods on that object until it is unlocked (the synchronized method returns). You can also synchronize a whole object.
By executing wait() a thread gives up its hold on a lock and goes to sleep. notifyAll() wakes up all threads that are waiting on a lock.
AOP
Useful Links
Notes
- A crosscutting concern is something that inherently relates to multiple components. Eg, logging, security, testing.
A join point is a well-defined point in the program flow such as method calls, object creation, field accesses.
A pointcut picks out certain join points.
- call(Signature)
- picks out a call to method based on Signature
- execution(Signature)
- picks out an execution of method based on Signature
- get(Signature)
- picks out a field get join point based on Signature
- set(Signature)
- picks out a field set join point based on Signature
- handles(TypePattern)
picks out an exception handler of any of the Throwable types of TypePattern
- instanceOf(ClassName)
picks out join points of currently executing objects of class ClassName
- within(ClassName)
picks out join points that are within code contained in ClassName
- withinCode(Signature)
- picks out join points that are within the member defined by method or constructor Signature
- cflow(pointcut)
- picks out all the join points in the control flow of the join points picked out by the pointcut
For example, the pointcut call(void Point.setX(int)) will pick out each join point that is a call to a method that has the signature void Point.setX(int)
You can also use the logical operators (||, &&, !) with pointcuts.
- You can declare a named point cut. Eg, This will pick out pointcuts that match calls to the methods setX and setY.
1 pointcut move() { 2 call(void Point.setX(int)) || 3 call(void Point.setY(int)); 4 }
You can use wildcards in pointcuts. Eg, call(void Figure.make*(..)) will match any call to a void method on Figure that starts with 'make'.
cflow(move()) will pick out each join point that occurs in the dynamic context of the pointcut move().
A piece of advice is code that is executed at point cuts.
Aspects are the like classes but contain point cuts and advice.
