1.61k likes | 1.79k Views
Comp 110 Representation. Instructor: Jason Carter. More on Objects. Testing objects and writing stubs Calling getters/setters from programs Two-way dependencies Representations with errors Default values of variables Null value Class variables/methods Polymorphism vs. overloading
E N D
Comp 110Representation Instructor: Jason Carter
More on Objects • Testing objects and writing stubs • Calling getters/setters from programs • Two-way dependencies • Representations with errors • Default values of variables • Null value • Class variables/methods • Polymorphism vs. overloading • Structure vs. atomic types • Physical vs. logical structure • Graphics types • Top-down, bottom-up, middle-out programming
Importance of Testing Experienced programmers make errors Important to test programs
Corvette vs. BMI Spreadsheet Usage • Test new Corvette for mileage • Get car from Corvette factory • Drive car • Compare actual and advertised mileage • Test BMISpreadsheet for correctness • Instantiate class ABMISpreadsheet • Give values to height and weight • Compare actual and computed BMI How to do this in a programmed method such as test ?
Interactive vs. Programmed Setter bmiSpreadsheet.setHeight(1.77);
Interactive vs. Programmed Getter doublecomputedBMI = bmiSpreadsheet.getBMI();
BMI Tester publicclassABMISpreadsheetTester { publicvoidtest ( doubletheHeight, doubletheWeight, doubletheCorrectBMI) { } }
BMI Tester (Edit) publicclassABMISpreadsheetTester { publicvoidtest ( doubletheHeight, doubletheWeight, doubletheCorrectBMI) { ABMISPreadsheetbmiS = new ABMISpreadsheet(theHeight,theWeight); double computedBMI = bmiS.betBMI(); … System.out.println(theCorrectBMI – computedBMI); } }
BMI Tester (Edit) publicclassABMISpreadsheetTester { publicvoidtest ( doubletheHeight, doubletheWeight, doubletheCorrectBMI) { BMISpreadsheetbmiS = new ABMISpreadsheet(); bmiS.setHeight(theHeight); bmiS.setWeight(theWieght); double computedBMI = bmiS.betBMI(); … System.out.println(theCorrectBMI – computedBMI); } }
Testing BMI Spreadsheet Steps taken by ABMISpreadsheetTester?
BMI Tester publicclassABMISpreadsheetTester { publicvoidtest ( doubletheHeight, doubletheWeight, doubletheCorrectBMI) { BMISpreadsheetbmiSpreadsheet = new ABMISpreadsheet(theHeight, theWeight); doublecomputedBMI = bmiSpreadsheet.getBMI(); System.out.println("------------"); System.out.println("Height:" + theHeight); System.out.println("Weight:" + theWeight); System.out.println("Expected BMI:" + theCorrectBMI); System.out.println("Computed BMI:" + computedBMI); System.out.println( "Error:" + (theCorrectBMI - computedBMI)); System.out.println("------------"); } publicvoid test () { test(1.65, 60, 20); test(1.55, 60, 25); test(1.8, 65, 20); } }
BMI Tester (Edit) publicclassABMISpreadsheetTester { publicvoidtest ( doubletheHeight, doubletheWeight, doubletheCorrectBMI) { BMISpreadsheetbmiSpreadsheet = new ABMISpreadsheet(theHeight, theWeight); doublecomputedBMI = bmiSpreadsheet.getBMI(); System.out.println("------------"); System.out.println("Height:" + theHeight); System.out.println("Weight:" + theWeight); System.out.println("Expected BMI:" + theCorrectBMI); System.out.println("Computed BMI:" + computedBMI); System.out.println( "Error:" + (theCorrectBMI - computedBMI)); System.out.println("------------"); } publicvoid test () { } }
BMI Tester publicclassABMISpreadsheetTester { publicvoidtest ( doubletheHeight, doubletheWeight, doubletheCorrectBMI) { BMISpreadsheetbmiSpreadsheet = new ABMISpreadsheet(theHeight, theWeight); doublecomputedBMI = bmiSpreadsheet.getBMI(); System.out.println("------------"); System.out.println("Height:" + theHeight); System.out.println("Weight:" + theWeight); System.out.println("Expected BMI:" + theCorrectBMI); System.out.println("Computed BMI:" + computedBMI); System.out.println( "Error:" + (theCorrectBMI - computedBMI)); System.out.println("------------"); } publicvoid test () { test(1.65, 55, 2.0); test(1.55, 60, 25); test(1.80, 65, 20); } } Actual Parameters Formal Parameters
Traditional Approach • Code the complete object to be tested • Write and use test object • Recode and retest if necessary • Testing is an afterthought • All methods tested together – hard to pinpoint bugs ABMISpreadsheet Tested Code ABMISpreadsheetTester Tester
Incremental Testing • Tested code and tester could evolve concurrently • getBMI() cannot be tested until it has been written ABMISpreadsheet Tested Code ABMISpreadsheetTester Tester
Test-First • Write the complete tester, defining the expected behavior of the tested object • Code the object with only stubs • Test, implement a stub and retest Stubs for Tested Code ABMISpreadsheet with Stubs Tester ABMISpreadsheetTester Implement or change the stub ABMISpreadsheet with a stub (re) implemented
Steps in Creating and Testing a New Class • Write the interface • Create a class with stubs for each interface method and constructor • If method is procedure method does nothing • If method is function, it returns 0 or null value • No variables need be declared as this point! • Write a tester for it • Write/rewrite in one or more stub methods • Use tester and ObjectEditor • If tester results and ObjectEditor results not correct, go back to 4 Steps may be combined for simple classes!
Writing the Interface publicinterface BMISpreadhsheet { publicdoublegetHeight() ; publicvoidsetHeight (doublenewHeight) ; publicdoublegetWeight() ; publicvoidsetWeight(doublenewWeight) ; publicdoublegetBMI() ; }
Stubs publicclassABMISpreadsheetimplements BMISpreadhsheet { publicABMISpreadsheet( doubletheInitialHeight, doubletheInitialWeight) {} publicABMISpreadsheet() {} publicdoublegetHeight() {} publicvoidsetHeight (doublenewHeight) {} publicdoublegetWeight() {} publicvoidsetWeight(doublenewWeight) {} publicdoublegetBMI() {} } No variables!
Stubs (Edit) publicclassABMISpreadsheetimplements BMISpreadhsheet { publicABMISpreadsheet( doubletheInitialHeight, doubletheInitialWeight) {} publicABMISpreadsheet() {} publicdoublegetHeight() {return 0;} publicvoidsetHeight (doublenewHeight) {} publicdoublegetWeight() {return 0;} publicvoidsetWeight(doublenewWeight) {} publicdoublegetBMI() {return 0;} } No variables!
Stubs publicclassABMISpreadsheetimplements BMISpreadhsheet { publicABMISpreadsheet( doubletheInitialHeight, doubletheInitialWeight) {} publicABMISpreadsheet() {} publicdoublegetHeight() { return 0; } publicvoidsetHeight (doublenewHeight) {} publicdoublegetWeight() { return 0; } publicvoidsetWeight(doublenewWeight) {} publicdoublegetBMI() { return 0; } } No variables!
Using Tester We know what the correctness criteria are!
BMI Tester publicclassABMISpreadsheetTester { publicvoidtest ( doubletheHeight, doubletheWeight, doubletheCorrectBMI) { BMISpreadsheetbmiSpreadsheet = new ABMISpreadsheet(theHeight, theWeight); doublecomputedBMI = bmiSpreadsheet.getBMI(); System.out.println("------------"); System.out.println("Height:" + theHeight); System.out.println("Weight:" + theWeight); System.out.println("Expected BMI:" + theCorrectBMI); System.out.println("Computed BMI:" + computedBMI); System.out.println( "Error:" + (theCorrectBMI - computedBMI)); System.out.println("------------"); } publicvoid test () { } } Interface as type Calling constructor Calling getter
Calling Parameterless Constructor and Setters publicclassABMISpreadsheetTester { publicvoidtest ( doubletheHeight, doubletheWeight, doubletheCorrectBMI) { BMISpreadsheetbmiSpreadsheet = newABMISpreadsheet(); bmiSpreadsheet.setHeight(theHeight); bmiSpreadsheet.setWeight(theWeight); doublecomputedBMI = bmiSpreadsheet.getBMI(); System.out.println("------------"); System.out.println("Height:" + theHeight); System.out.println("Weight:" + theWeight); System.out.println("Expected BMI:" + theCorrectBMI); System.out.println("Computed BMI:" + computedBMI); System.out.println( "Error:" + (theCorrectBMI - computedBMI)); System.out.println("------------"); } } Parameterless constructor Calling setter Constructors with parameters make code more compact
Object vs. Primitive Variable publicclassABMISpreadsheetTester { publicvoidtest ( doubletheHeight, doubletheWeight, doubletheCorrectBMI) { BMISpreadsheetbmiSpreadsheet = newABMISpreadsheet(theHeight, theWeight); doublecomputedBMI = bmiSpreadsheet.getBMI(); System.out.println("------------"); System.out.println("Height:" + theHeight); System.out.println("Weight:" + theWeight); System.out.println("Expected BMI:" + theCorrectBMI); System.out.println("Computed BMI:" + computedBMI); System.out.println( "Error:" + (theCorrectBMI - computedBMI)); System.out.println("------------"); } } Primitive Variable Primitive Variable Object Variable Object Variable
Uninitialized Variables publicclassABMISpreadsheetTester { publicvoidtest ( doubletheHeight, doubletheWeight, doubletheCorrectBMI) { BMISpreadsheetbmiSpreadsheet; doublecomputedBMI ; System.out.println("------------"); System.out.println("Height:" + theHeight); System.out.println("Weight:" + theWeight); System.out.println("Expected BMI:" + theCorrectBMI); System.out.println("Computed BMI:" + computedBMI); System.out.println( "Error:" + (theCorrectBMI - computedBMI)); System.out.println("------------"); } } Uninitialized Primitive Variable Uninitialized Object Variable
Default Values for Variables Primitive Variables variables memory Legal double values doublecomputedBMI; computedBMI; 0.0 double weight; weight; 0.0 Object Variables BMISpreadsheetbmiSpreadsheet; bmiSpreadsheet; null Illegal BMISpreadsheet value
Invoking Methods on null • bmiSpreadsheet.getBMI() • null pointer exception • Exception is an unexpected event (error) • Guilty method will be terminated and exception reported • Will see other exceptions later
Mathematical Point X . R Y q .
(3,2) pixels Java Coordinate System (0,0) X X and Y coordinates must be int values Radius and Angle can be double Y Angle is a decimal value between 0 and 2
Point Interface publicinterface Point { publicintgetX(); publicintgetY(); publicdoublegetAngle(); publicdoublegetRadius(); } Read-only properties defining immutable object!
Point Representations • X, Y (Cartesian Representation) • Radius, Angle (Polar Representation) • X, Radius • X, Y, Radius, Angle • …
Stubs for ACartesianPoint publicclassACartesianPointimplements Point { publicACartesianPoint(inttheX, inttheY) { } publicintgetX() { return 0; } publicintgetY() { return 0; } publicdoublegetAngle() { return 0; } publicdoublegetRadius() { return 0; } }
ACartesianPoint Tester publicclassACartesianPointTester { publicvoidtest (inttheX, inttheY, doubletheCorrectRadius, doubletheCorrectAngle) { Point point= newACartesianPoint (theX, theY); doublecomputedRadius = point.getRadius(); doublecomputedAngle = point.getAngle(); System.out.println("------------"); System.out.println(“X:" + theX); System.out.println(“Y:" + theY); System.out.println("Expected Radius:" + theCorrectRadius); System.out.println("Computed Radius:" + computedRadius); System.out.println(“Radius Error:" + (theCorrectRadius - computedRadius)); System.out.println("Expected Angle:" + theCorrectAngle); System.out.println("Computed Angle:" + computedAngle); System.out.println(“Angle Error:" + (theCorrectAngle - computedAngle)); System.out.println("------------"); } publicvoid test () { test (10, 0, 10.0, 0); // 0 degree angle test (0, 10, 10.0, Math.PI / 2); // 90 degree angle } }
Algorithms Cartesian Representation R = sqrt (X2 * Y2) X = arctan (Y/X) . R Y Polar Representation q X = R*cos() . Y = R*sin()
Class: ACartesianPoint publicclassACartesianPointimplements Point { int x, y; publicACartesianPoint(inttheX, inttheY) { x = theX; y = theY; } publicintgetX() { return x; } publicintgetY() { return y; } publicdoublegetAngle() { returnMath.atan((double) y/x); } publicdoublegetRadius() { returnMath.sqrt(x*x + y*y); } }
Class: APolarPoint publicclassAPolarPointimplements Point { double radius, angle; publicAPolarPoint(double theRadius, doubletheAngle) { radius = theRadius ; angle = theAngle; } publicintgetX() { return (int) (radius*Math.cos(angle)); } publicintgetY() { return (int) (radius*Math.sin(angle)); } publicdoublegetAngle() { return angle; } publicdoublegetRadius() { return radius; } }
Using the Interface and Its Implementations Point point1 = newACartesianPoint (50, 50); Point point2 = newAPolarPoint (70.5, Math.pi()/4); point1 = point2; Constructor chooses implementation Constructor cannot be in interface
Representing Geometric Objects • Geometric example to show multiple useful implementations of an interface • Most geometric objects have multiple representations
Java Graphics Y X