Generics OOP Tirgul
What is it good for ? Stack myStack = new Stack() ; // old version (1.4.2) myStack.push(new Integer(0)) ; int x = ((Integer) myStack.pop()).intValue() ; // annoying cast Stack myStack = new Stack () ; myStack.push(new Integer(0)) ; int x = myStack.pop().intValue() ; // no cast is needed Using generics, the code looks like this: Without Using generics, the code looks like this: More readable and more typesafe!
Implementation Issues Defining a Generic Stack public interface Stack { public boolean empty() ; public E peek() ; public E pop() ; public E push (E item) ; public E peek() ; } Using a single letter in UPPER CASE for the type is the acceptable naming convention
Implementation Issues Generics and inheritance Stack objectStack = new Stack () ; Stack integerStack=objectStack ; // illegal assignment Although Integer Inherits Object, Stack is a different type from Stack
Remark Stack objectStack = new Stack () ; Stack myStack = objectStack ; // is this legal ? (compile // time warning) Integer x = new Integer(0); myStack.push(x) ; // what happens here? (Runtime error)
Implementation Issues Generics and inheritance(2) public void printAndEmptyStack(Stack stack) { while (!stack.empty()) System.out.println(stack.pop()); } What is the problem when using generics ? How do we implement it using generics ?
Implementation Issues Generics and inheritance(3) Using wildcards : public void printAndEmptyStack( Stack stack) { while (!stack.empty()) System.out.println(stack.pop()); } Stack is a called “stack of unknowns”.
Implementation Issues Generics and inheritance(4) Anima l HorseZebraFrog
Implementation Issues Generics and inheritance(5) Assume we want to print and empty only stacks of animals, i.e Stack, Stack etc. The correct syntax is : public void printAndEmptyStack ( Stack stack) { while (!stack.empty()) System.out.println(stack.pop()); } Note: Stack given to this function is a legal type.
Implementation Issues Generics and inheritance(6) Is this code legal ? public void addElement ( Stack s) { s.add (new Frog() ) ; } What if the parameter given to the method was Stack ?
Generic Methods Version 1: public static void insertElementToStack (Object element, Stack c) { if (element != null) c.push(element) ; //compile time error } Version 2 : public static void insertElementToStack (? element, Stack c) { if (element != null) c.push(element) ; } // compile time error – no such type “?”
Generic Methods(2) Version 3: public static void insertElementToStack (T element, Stack c) { if (element != null) c.push(element) ; } // this version is the way to do it
Generic Methods(3) public static void insertElementToStack (E element, Stack c) { if (element != null) c.push(element) ; } // this allows inserting elements which inherit from a base // class
Arrays public class Stack { private final static int INITIAL_CAPACITY = 100 ; private E[] _stack = new E[INITIAL_CAPACITY]; // compile time // error }
Exercises Is the following legal : public static void add (String s, Stack stack) { stack.push(s) ; } public static void main(string args[] ) { Stack s = new Stack (); add( “hapoel”, s) ; }
Exercises(2) Is the following legal : public static void add (String s, Stack stack) { stack.push(s) ; } public static void main(string args[] ) { Stack s = new Stack () ; add( “hapoel”, s) ; }
Exercises(3) Is the following legal : public static void addNull( Stack stack) { stack.push( null ) ; } public static void main(string args[] ) { Stack s = new Stack (); addNull(s) ; }