// sometimes generics is enough class cell1 { T info; cell1 next; public cell1(T x, cell1 y) {info=x; next=y;} } // but want to do more class cell2> { T info; cell2 next; public cell2(T x, cell2 y) {info=x; next=y;} // check if list is sorted public boolean sorted() { boolean ax = true; for(cell2 i=this; i.next!=null && ax;i=i.next) if (i.info.compareTo(i.next.info)>0) ax = false; return ax; }//sorted }//cell2 -- this is what we did for heaps. // but this is also sometimes not enough. sometimes we won't know how // to define a procedure until we know exactly what T is. abstract class abcell { T info; abcell next; // no constructor in abstract class! public abstract T merge(); // merge all elements of list into one value // other methods in abstract class can "call" merge public void printmerged() // can't call right now, why? { T x = merge(); System.out.println(x); }// printmerged is "polymorphic" }//abcell class cell3a extends abcell { // inheriting Double info and abcell next public cell3a(Double x, cell3a y) {info=x; next=y;} // now implement merge public Double merge() { Double ax = 0.0; for (abcell i=this;i!=null;i=i.next) ax = ax + i.info; return ax; } }// cell3a class cell3b extends abcell { // inheriting Double info and abcell next public cell3b(Double x, cell3b y) {info=x; next=y;} // now implement merge public Double merge() { Double ax = this.info; for (abcell i=this;i!=null;i=i.next) ax = ax * i.info; return ax; } }// cell3b class cell3c extends abcell { public cell3c(String x, cell3c y) {info=x; next=y;} public String merge() { String ax = ""; for(abcell i=this;i!=null;i=i.next) ax = i.info + ax; return ax; } } public class abstracts { public static void main(String[] aaa) { cell3a A = new cell3a(1.2,new cell3a(2.4,null)); cell3c B = new cell3c("world",new cell3c("hello ",null)); System.out.println(A.merge()); B.printmerged(); // can now call printmerged. } }