450 likes | 469 Views
Review : abstract. abstract method a method without implementation abstract class an “incomplete” class force concrete subclasses to implement abstract methods (if any) cannot be instantiated. The Student Class Hierarchy. class Student { : public String getGrade() {
E N D
Review : abstract • abstract method • a method without implementation • abstract class • an “incomplete” class • force concrete subclasses to implement abstract methods (if any) • cannot be instantiated
The Student Class Hierarchy class Student { : publicString getGrade() { return “ERROR”; } } class PassFailStudent extends Student { : publicString getGrade() { return (average > 70) ? “pass” : “fail”; } } class LetterGradeStudent extends Student { : publicString getGrade() { if (average > 90) return “A”; else if (average > 70) return “B”; else if (average > 40) return “C”; else return “D”; } }
students LetterGradeStudent PassFailStudent PassFailStudent Using Student Class Student students[] = new Student[numOfStudents]; // create students : if (enrolledAsPassFail) students[i] = new PassFailStudent(..); else students[i] = new LetterGradeStudent(..); // prints the name and final grade of all students for (int i = 0; i < numOfStudents;i++) System.out.println( students[i].getName() + “\t” + students[i].getGrade());
Abstract Student Class abstract class Student { : publicabstractString getGrade(); } class PassFailStudent extends Student { : publicString getGrade() { return (average > 70) ? “pass” : “fail”; } } class LetterGradeStudent extends Student { : publicString getGrade() { if (average > 90) return “A”; else if (average > 70) return “B”; else if (average > 40) return “C”; elsereturn “D”; } }
Interface • “Pure” abstract class • Must contain only constant members and abstract methods • Members are publicfinal static by default • Methods are publicabstract by default
Implements • an interface does not contain any implementation • a class provides implementations • We say : a class implements an interface
interface And implements interface Hero { boolean NEVER_DIES = true; void swim(); void fight(); void jump(); }; class Jedi implements Hero { publicvoid fight() { // swing light saber } publicvoid swim() { ... } publicvoid jump() { ... } } class WesternHero implements Hero { publicvoid fight() { // punch } publicvoid swim() { ... } publicvoid jump() { ... } }
More interface Examples interface NumericSet { void add(Number n); void remove(Number n); void union(NumericSet n); void intersect(NumbericSet n); boolean isEmpty(); boolean contains(Number n); int size(); } interface Printable { void print(); }
More implements Examples class ArraySet implements NumericSet, Printable { publicvoid add(Number n) { ... } publicvoid remove(Number n) { ... } publicvoid union(NumericSet n) { ... } publicvoid intersect(NumbericSet n) { ... } publicboolean isEmpty() { ... } publicboolean contains(Number n) { ... } publicint size() { ... } publicvoid print() { ... } }
a class can implementmore than one interfaces A implements B =“A has the behaviors of B” a class can only extendone other class A extends B = “A is a kind of B” Differences
Extending Interface • We can extend an interface • interface A extends B : B is called superinterface • We can override methods in superinterface • We can overload methods in superinterface
Extending interface interface FlyingHero extends Hero { void fly(); } interface RoboticHero extends Hero { void fight(Weapon w); void swim() throws RustException; } interface SortedSet extends NumericSet { boolean isSorted(); void sort(); Number first(); Number last(); } interface DoubleClickable extends Clickable { void doubleClicked(); }
Try it out yourself 1 • can we declare a class without abstract methods as “abstract” ? abstractclass A { int f() { return 1; } }
Try it out yourself 2 • must we implement all abstract methods from the interface ? interface I { int f(); int g(); } class A implements I { int f() { returns 1; } }
Try it out yourself 3 • can a class implement two interfaces with methodsof the same name? interface I1 { int f(); } interface I2 { int f(); } interface I3 { double f(); } class A implements I1, I2 { int f() { return 1; } } class B implements I1, I3 { int f() { return 1; } double f() { return 1.0; } }
Bugs • Programming Errors • First bug • A moth stuck in a Harvard Mark II mainframe in 1947.
Bugs are bad • 1990 – AT&T long distance service failed for 9 hours and was traced to a single faulty line of code • 1991 – Scud missile killed 28 soldiers because a bug caused the Patriot defense system to be off by 0.34 seconds • 2000 – Y2K
Today’s Lecture • How to prevent bugs ? • Understand the problem • Understand Java • Follow good programming practices • How to find bugs ? • Testing • How to kill bugs ?
Program Development Design Implement Testing
Program Design : Classes Studentdouble averageGradeint grades[6]double weight[6]calcAverageGrade()getAverageGrade() Coursedouble averageGradedouble maxdouble mindouble sumint numOfStudentStudent students[]calcAverageGrade()getAverageGrade() LetterGradeStudentprintGrade() PassFailStudentprintGrade()
Program Design : Pseudocode Average grade for studentsfor ( i = 0 .. 6) average += grade[i]*weight[i]return average Get inputget number of studentsfor i = 1 .. number of students get name get enrollment status get all six grades if enroll as pass fail then create a PassFailStudent else create a LetterGradeStudent Average Grade for coursefor each student sum += student’s weight averagereturn sum/number of students;
pass/fail ? name 6 grades create a student Program Design : Data Flow final grade get final grade Student obj calc student’s average grade average grade
i = 0 i == # of students ? get nameget statusget grades increment i Program Design : Control Flow
Good Program vs. Bad Program • Easy to Read • Good Comments • Meaningful Names • Properly Indented • Blank Lines • Well-Designed • Cover all cases • Anticipate Changes • Facilitate Reuse
Very Bad Program // A program that reads some inputs and outputs some stuffs class P2Q3 { publicstaticvoid main(String X[]) { int temp = 0, temp2 = 0, s = 0, c=0, M = 0, X[]; TokenReader tr = new TokenReader(); System.out.println(“number:”); int N=tr.ReadInt(); X = newint[N];N = tr.ReadInt(); while (N!=0){s+=N;if (N>M) M=N;X[temp] = N; temp++; System.out.println(“number”);N=tr.ReadInt(); temp2++;} System.out.println(s + “ “ + temp2 + “ “ + temp); temp2 = temp1 = 0; while (temp2 < X.length) System.out.println(X[temp1]) temp2++; temp1++;}}
Better Program class P2Q3 { publicstaticvoidmain(String X[]) { // sum – total of values entered so far // max – maximum of values entered so far // count – number of values entered int sum = 0, count = 0, max = Integer.MAX_VALUE; TokenReader tr = new TokenReader(); System.out.println(“Enter number :”); int input = tr.ReadInt(); // keep reading until user enters 0 while (input != 0){ sum += input; // compare current input with maximum so far. update // maximum so far if input is larger. if ( input < max ) { max = input; count++; } System.out.println(“Enter number :”); input = tr.ReadInt(); } } }
Good Design • Anticipate Changes • Reusable • Encapsulation • Think “LEGO”
publicstaticvoidmain(String args[]) { TokenReader in = new TokenReader(); int histogram = new int[10]; for (int i = 0; i < 10; i++) { histogram[i] = 0; } int input = in.readInt(); while (input != 0) { if (input > 1 && input <= 10) { histogram[0]++; } elseif (input > 10 && input <= 20) { histogram[1]++; } elseif (... : : // smarter implementation // int n = (input – 1)/10; // histogram[n]++; Bad Histogram Program
What if .. • create histogram for data between 1 .. 200 ? • tally data for smaller intervals ? 1 – 5 | ** 6 – 10 | ***** 11 – 15 | * : : 196 – 200 | *** • draw a histogram for average grade ?
class Histogram { int numOfBuckets, bucketSize, buckets[]; public Histogram(int numOfBuckets, int bucketSize) { this.numOfBuckets = numOfBuckets; this.bucketSize = bucketSize; buckets = new int[numOfBucket]; for (int j = 0; j < buckets.length; j++) buckets[j] = 0; } publicvoid addData(int data) { buckets[(data-1)/bucketSize]++; } publicvoid print() { for (int j = 0; j < numOfBucket; j++) { System.out.println((j*bucketSize+ 1)+ “-” + ((j+1)*bucketSize))); for (int k = 0; k < buckets[j]; k++) System.out.print(“*”); Sysmte.out.println(); } } } Good Histogram Program
Bug Preventions • code reuse • fewer lines of code to write, fewer bugs • anticipate changes • fewer lines of code to change,fewer bugs • encapsulation • bugs are confined to one place, easier to detect and fix.
Good Programs • Easy to read • blank lines • indentation • comments • meaningful names • Easy to read, easy to spot bugs !
Finding Bugs • Wrong attitude : “My program works ! I am done.” • Did you test it with all possible inputs ? • negative numbers ? • zero ? • Did you test all possible paths of execution ?
Component Testing • Another motivation for encapsulations ! • Test each component separately • Make sure they worked before using them
Debugging Techniques : Think “high-level” • scan from left to right • swap two adjacent elements if they are out of order • repeat until everything is in order
Debugging Techniques :Printout • Print out your code • Spread it on a large table • Walkthrough your code • Draw diagrams • Make notes
Debugging Techniques : Explain it to Someone Else • Old Chinese Proverb : “Onlookers see most of the game; Players see very little”
Debugging Techniques :System.err.println • Let you inspect the intermediate value of variables 53 2147483647 034 2147483647 010 2147483647 0 82 2147483647 0 72 2147483647 0 • Can you guess what is wrong now ?
Using System.err.println class P2Q3 { publicstaticvoidmain(String X[]) { : : // keep reading until user enters 0 while (input != 0){ sum += input; // compare current input with maximum so // far. update maximum so far if input // is larger. if ( input < max ) { max = input; count++; } System.err.println(input + “ “ + max + “ “ + count); System.out.println(“Enter number :”); input = tr.ReadInt(); } } }
Debugging Techniques : assert • a method to make sure that your invariants are true. void assert(boolean condition, String errorMessage) {if (!condition)thrownew Error(errorMessage); }
Using assert class Histogram { int numOfBuckets; int bucketSize; int buckets[]; : : publicvoid addData(int data) { assert(data >= 0 && data < numOfBuckets*bucketSize, “data” + data + “is out of range.”); buckets[(data-1)/bucketSize]++; } : : }
Debugging Techniques : assert • TheError exception will cause the stack trace to be printed. java.lang.Error: data 364 is out of rangeat java.lang.Throwable.<init>at java.lang.Error.<init>at Histogram.assertat Histogram.addData at P2Q4.createHistogramat P2Q4.main
Summary • Bug Prevention • understand the problem and language • design before sit in front of computer • design for change/reuse • Bug Discovery • test all flow of controls • test small components separately before using them
Summary • Bug Termination • re-think your algorithm from a higher-level • manually trace through your program • explain your program to others • System.err.println • assert • use a debugger