150 likes | 169 Views
CS100J Lecture 25. Previous Lecture Inheritance Method overriding Polymorphism This Lecture Application of inheritance “Higher-order" methods Abstract classes Visibility modifier: protected. Recall class ML: Method add. // x + y public static ML add (ML x, ML y) {
E N D
CS100J Lecture 25 • Previous Lecture • Inheritance • Method overriding • Polymorphism • This Lecture • Application of inheritance • “Higher-order" methods • Abstract classes • Visibility modifier: protected Lecture 25
Recall class ML: Method add // x + y public static ML add(ML x, ML y) { if ( x.isEmpty() || y.isEmpty() ) returnnew ML(0,0); elseif ( x.isScalar() ){ ML result = new ML(y.h, y.w); ml scalarValue = x.values[0][0]; for (int r = 0; r < y.h; r++) for (int c = 0; c < y.w; c++) result.values[r][c] = ml.add( scalarValue, y.values[r][c] ); return result; } elseif ( y.isScalar() ){ ML result = new ML(x.h, x.w); ml scalarValue = y.values[0][0]; for (int r = 0; r < x.h; r++) for (int c = 0; c < x.w; c++) result.values[r][c] = ml.add( x.values[r][c], scalarValue); return result; } // continued... Lecture 25
Recall class ML: Method add, continued elseif (x.h != y.h || x.w != y.w) thrownew RuntimeException( ”matrix dimensions do not match"); else { ML result = new ML(x.h, x.w); for (int r = 0; r < x.h; r++) for (int c = 0; c < x.w; c++) result.values[r][c] = ml.add( x.values[r][c], y.values[r][c]); return result; } // end of method add } Lecture 25
Recall Class ml: Arithmetic Methods publicstatic ml add(ml x, ml y) { return new ml(x.re + y.re, x.im + y.im); } publicstatic ml sub(ml x, ml y) { return new ml(x.re - y.re, x.im - y.im); } /* other operators: .* ./ < <= > >= == ~= unary- etc. */ Lecture 25
Recall the Critique of ML Method add • Most of the code (all but the 3 invocations of ml.add) has nothing to do with the fact that this is the method for addition. • To implement subtraction, almost all code (except for the 3 invocations of ml.add) would be identical. • We could implement each of the other element-by-element matrix operations in about 30 seconds each: • Copy the definition of ML.add • Replace “add” with “sub”, or “mult”, or “div”, etc. • Write ml.add, ml.mult, ml.div, etc. • Terrible: • Grotesque duplication of code. • Loss of “single point of change”. • No abstraction. • Surely, there must be a way to avoid duplicating the common code. • Coming later... Now is that time Lecture 25
class ML: Method Binary // x op y publicstatic ML Binary( OP o, // where method o.op combines 2 ml’s. ML x, // left operand. ML y // right operand. ) { if (x.isEmpty() || y.isEmpty()) returnnew ML(0,0); elseif (x.isScalar()){ ML result = new ML(y.h, y.w); ml scalarValue = x.values[0][0]; for (int r = 0; r < y.h; r++) for (int c = 0; c < y.w; c++) result.values[r][c] = o.op( scalarValue, y.values[r][c]); return result; } // continued... Lecture 25
class ML: Method Binary, continued elseif ( y.isScalar() ){ ML result = new ML(x.h, x.w); ml scalarValue = y.values[0][0]; for (int r = 0; r < x.h; r++) for (int c = 0; c < x.w; c++) result.values[r][c] = o.op( x.values[r][c], scalarValue); return result; } elseif (x.h != y.h || x.w != y.w) thrownew RuntimeException( ”matrix dimensions do not match"); else { ML result = new ML(x.h, x.w); for (int r = 0; r < x.h; r++) for (int c = 0; c < x.w; c++) result.values[r][c] = o.op( x.values[r][c], y.values[r][c]); return result; } } // end of ML method add Lecture 25
Class OP: a class of binary operations class OP { // A “placeholder” binary operation. ml op(ml x, ml y) { return null; } } class BinaryAdd extends OP { ml op(ml x, ml y) { return ml.add(x,y); } } class BinarySub extends OP { ml op(ml x, ml y) { return ml.sub(x,y); } } Lecture 25
Class ML: Methods add and sub // x + y publicstatic ML add(ML x, ML y) { return ML.Binary(new BinaryAdd(), x, y); } // x - y publicstatic ML sub(ML x, ML y) { return ML.Binary(new BinarySub(), x, y); } Lecture 25
Sample Client Code // ones(2,3) + ones(2,3) ML.add( ML.ones(2,3), ML.ones(2,3) ) • Evaluation of expression ML.add(…,…) • invokes ML.Binary(new BinaryAdd(), …, …) • which invokes BinaryAdd.op(…,…) • to add pairs of complex matrix elements, which invokes ml.add(…,…) • to do the complex addition. Lecture 25
Abstract Classes abstract class OP { // A “placeholder” binary operation. abstract ml op(ml x, ml y); } class BinaryAdd extends OP { ml op(ml x, ml y) { return ml.add(x,y); } } class BinarySub extends OP { ml op(ml x, ml y) { return ml.sub(x,y); } } Lecture 25
An Application of Inheritance abstract class OP { staticint count = 0; // # ml operations. // A “placeholder” binary operation. abstract ml op(ml x, ml y); } class BinaryAdd extends OP { ml op(ml x, ml y) { count++; return ml.add(x,y); } } class BinarySub extends OP { ml op(ml x, ml y) { count++; return ml.sub(x,y); } } Lecture 25
Visibility Modifier: Protected • Recall the visibility modifiers of constructors, methods, or fields: • public A public item is visible anywhere in the program • private A private items is only visible in the class in which the item is declared or defined. In particular, a private item declared or defined in class c is not visible in the subclasses of a class c • The new visibility modifier • protected A protected item is visible in the class in which the item is declared or defined, and in any subclasses of that class Lecture 25
Visibility Modifier: Protected abstract class OP { // # ml operations. protectedstaticint count = 0; // A “placeholder” binary operation. abstract ml op(ml x, ml y); static intgetCount() { return count; } } class BinaryAdd extends OP { ml op(ml x, ml y) { count++; return ml.add(x,y); } } class BinarySub extends OP { ml op(ml x, ml y) { count++; return ml.sub(x,y); } } Lecture 25
Sample Client Code // ones(2,3) + ones(2,3) System.out.println( ML.add( ML.ones(2,3), ML.ones(2,3) ) ); /* Output the total number of primitive ml operations performed by all matrix operations to date. */ System.out.println( ”#: ” + OP.getCount() ); • Output 2 2 2 2 2 2 #: 6 Lecture 25