200 likes | 346 Views
Generics. OOP Tirgul 8 2006. What is it good for ?. Without Using generics, the code looks like this:. Stack myStack = new Stack() ; // old version (1.4.2) myStack.push(new Integer(0)) ; int x = ((Integer) myStack.pop()).intValue() ; // annoying cast.
E N D
Generics OOP Tirgul 8 2006
What is it good for ? Without Using generics, the code looks like this: Stack myStack = new Stack() ; // old version (1.4.2) myStack.push(new Integer(0)) ; int x = ((Integer) myStack.pop()).intValue() ; // annoying cast Using generics, the code looks like this: Stack<Integer> myStack = new Stack<Integer>() ; myStack.push(new Integer(0)) ; int x = myStack.pop().intValue() ; // no cast is needed More readable and more typesafe!
Implementation IssuesDefining a Generic Stack public interface Stack<E> { 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 IssuesGenerics and inheritance Stack<Object> objectStack = new Stack<Object>() ; Stack<Integer> integerStack=objectStack ; // illegal assignment Although Integer Inherits Object, Stack<Integer> is a different type from Stack<Object>
Remark Stack<String> objectStack = new Stack<String>() ; Stack myStack = objectStack ; // is this legal ? (compile // time warning) Integer x = new Integer(0); myStack.push(x) ; // what happens here? (Runtime error)
Implementation IssuesGenerics 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 IssuesGenerics 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 IssuesGenerics and inheritance(5) Assume we want to print and empty only stacks of animals, i.e Stack<Animal>, Stack<Zebra> etc. The correct syntax is : public void printAndEmptyStack ( Stack<? extends Animal> stack) { while (!stack.empty()) System.out.println(stack.pop()); } Note: Stack<Animal> given to this function is a legal type.
Implementation IssuesGenerics and inheritance(6) Is this code legal ? public void addElement ( Stack<? extends Animal> s) { s.add (new Frog() ) ; } What if the parameter given to the method was Stack<Zebra> ?
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 <T> void insertElementToStack (T element, Stack<T> c) { if (element != null) c.push(element) ; } // this version is the way to do it
Generic Methods(3) public static <T,E extends T> void insertElementToStack (E element, Stack<T> c) { if (element != null) c.push(element) ; } // this allows inserting elements which inherit from a base // class
Arrays public class Stack<E> { 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<String> stack) { stack.push(s) ; } public static void main(string args[] ) { Stack<String> s = new Stack<String>(); 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<String> s = new Stack<String>() ; 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<String> s = new Stack<String>(); addNull(s) ; }