[{"data":1,"prerenderedAt":4404},["ShallowReactive",2],{"item-lessons-light-ch21-static-factories":3,"item-examples-light-ch21-static-factories":444,"item-exercises-light-ch21-static-factories":753,"item-lesson-full-ch21-static-factories-21":1070,"item-example-full-ch21-static-factories-21":1835,"item-exercise-full-ch21-static-factories-21":2660},[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,156,160,164,168,172,176,180,184,188,192,196,200,204,208,212,216,220,224,228,232,236,240,244,248,252,256,260,264,268,272,276,280,284,288,292,296,300,304,308,312,316,320,324,328,332,336,340,344,348,352,356,360,364,368,372,376,380,384,388,392,396,400,404,408,412,416,420,424,428,432,436,440],{"path":5,"title":6,"stem":7},"\u002Fshockwave-curriculum\u002Flessons\u002Fch01-why-java-for-frc\u002F1-why-java-for-frc","Why Java for FRC?","shockwave-curriculum\u002Flessons\u002Fch01-why-java-for-frc\u002F1.1-why-java-for-frc",{"path":9,"title":10,"stem":11},"\u002Fshockwave-curriculum\u002Flessons\u002Fch01-why-java-for-frc\u002F2-intro-to-algorithms-programming-and-compilers","Intro to Algorithms, Programming and Compilers","shockwave-curriculum\u002Flessons\u002Fch01-why-java-for-frc\u002F1.2-intro-to-algorithms-programming-and-compilers",{"path":13,"title":14,"stem":15},"\u002Fshockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F1-variables-and-data-types","Variables & Data Types","shockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F2.1-variables-and-data-types",{"path":17,"title":18,"stem":19},"\u002Fshockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F2-expressions-and-output","Expressions & Output","shockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F2.2-expressions-and-output",{"path":21,"title":22,"stem":23},"\u002Fshockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F3-assignment-and-input","Assignment & Input","shockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F2.3-assignment-and-input",{"path":25,"title":26,"stem":27},"\u002Fshockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F4-casting-and-ranges-of-values","Casting & Ranges of Values","shockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F2.4-casting-and-ranges-of-values",{"path":29,"title":30,"stem":31},"\u002Fshockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F5-compound-assignment-operators","Compound Assignment Operators","shockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F2.5-compound-assignment-operators",{"path":33,"title":34,"stem":35},"\u002Fshockwave-curriculum\u002Flessons\u002Fch03-apis-libraries-and-documentation\u002F1-apis-and-libraries","APIs and Libraries","shockwave-curriculum\u002Flessons\u002Fch03-apis-libraries-and-documentation\u002F3.1-apis-and-libraries",{"path":37,"title":38,"stem":39},"\u002Fshockwave-curriculum\u002Flessons\u002Fch03-apis-libraries-and-documentation\u002F2-documentation-with-comments-and-preconditions","Documentation with Comments and Preconditions","shockwave-curriculum\u002Flessons\u002Fch03-apis-libraries-and-documentation\u002F3.2-documentation-with-comments-and-preconditions",{"path":41,"title":42,"stem":43},"\u002Fshockwave-curriculum\u002Flessons\u002Fch03-apis-libraries-and-documentation\u002F3-packages-and-imports","Packages & Imports","shockwave-curriculum\u002Flessons\u002Fch03-apis-libraries-and-documentation\u002F3.3-packages-and-imports",{"path":45,"title":46,"stem":47},"\u002Fshockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F1-methods-signatures-and-parameters","Methods, Signatures & Parameters","shockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F4.1-methods-signatures-and-parameters",{"path":49,"title":50,"stem":51},"\u002Fshockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F2-calling-class-methods","Calling Class Methods","shockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F4.2-calling-class-methods",{"path":53,"title":54,"stem":55},"\u002Fshockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F3-using-the-math-class","Using the Math Class","shockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F4.3-using-the-math-class",{"path":57,"title":58,"stem":59},"\u002Fshockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F4-objects-instances-of-classes","Objects — Instances of Classes","shockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F4.4-objects-instances-of-classes",{"path":61,"title":62,"stem":63},"\u002Fshockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F5-creating-and-initializing-objects-constructors","Creating & Initializing Objects: Constructors","shockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F4.5-creating-and-initializing-objects-constructors",{"path":65,"title":66,"stem":67},"\u002Fshockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F6-calling-instance-methods","Calling Instance Methods","shockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F4.6-calling-instance-methods",{"path":69,"title":70,"stem":71},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F1-5.2-if-statements-and-for-loops","Control Structures: if Statements & For Loops","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.1-5.2-if-statements-and-for-loops",{"path":73,"title":74,"stem":75},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F10-nested-iteration","Nested Iteration","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.10-nested-iteration",{"path":77,"title":78,"stem":79},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F11-informal-runtime-analysis-of-loops","Informal Runtime Analysis of Loops","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.11-informal-runtime-analysis-of-loops",{"path":81,"title":82,"stem":83},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F12-switch-statements-and-expressions","switch Statements and Expressions","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.12-switch-statements-and-expressions",{"path":85,"title":86,"stem":87},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F3-algorithms-with-selection-and-repetition","Algorithms with Selection and Repetition","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.3-algorithms-with-selection-and-repetition",{"path":89,"title":90,"stem":91},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F4-boolean-expressions","Boolean Expressions","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.4-boolean-expressions",{"path":93,"title":94,"stem":95},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5-nested-if-statements","Nested if Statements","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.5-nested-if-statements",{"path":97,"title":98,"stem":99},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F6-compound-boolean-expressions","Compound Boolean Expressions","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.6-compound-boolean-expressions",{"path":101,"title":102,"stem":103},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F7-comparing-boolean-expressions-de-morgans-laws","Comparing Boolean Expressions (De Morgan's Laws)","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.7-comparing-boolean-expressions-de-morgans-laws",{"path":105,"title":106,"stem":107},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F8-while-loops","While Loops","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.8-while-loops",{"path":109,"title":110,"stem":111},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F9-implementing-selection-and-iteration-algorithms","Implementing Selection and Iteration Algorithms","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.9-implementing-selection-and-iteration-algorithms",{"path":113,"title":114,"stem":115},"\u002Fshockwave-curriculum\u002Flessons\u002Fch06-strings\u002F1-strings","Strings","shockwave-curriculum\u002Flessons\u002Fch06-strings\u002F6.1-strings",{"path":117,"title":118,"stem":119},"\u002Fshockwave-curriculum\u002Flessons\u002Fch06-strings\u002F2-string-algorithms","String Algorithms","shockwave-curriculum\u002Flessons\u002Fch06-strings\u002F6.2-string-algorithms",{"path":121,"title":122,"stem":123},"\u002Fshockwave-curriculum\u002Flessons\u002Fch07-the-class-blueprint\u002F1-anatomy-of-a-java-class","The Class Blueprint","shockwave-curriculum\u002Flessons\u002Fch07-the-class-blueprint\u002F7.1-anatomy-of-a-java-class",{"path":125,"title":126,"stem":127},"\u002Fshockwave-curriculum\u002Flessons\u002Fch07-the-class-blueprint\u002F2-methods-how-to-write-them","Methods: How to Write Them","shockwave-curriculum\u002Flessons\u002Fch07-the-class-blueprint\u002F7.2-methods-how-to-write-them",{"path":129,"title":130,"stem":131},"\u002Fshockwave-curriculum\u002Flessons\u002Fch07-the-class-blueprint\u002F3-methods-passing-and-returning-references-of-an-object","Methods: Passing & Returning References of an Object","shockwave-curriculum\u002Flessons\u002Fch07-the-class-blueprint\u002F7.3-methods-passing-and-returning-references-of-an-object",{"path":133,"title":134,"stem":135},"\u002Fshockwave-curriculum\u002Flessons\u002Fch07-the-class-blueprint\u002F4-class-static-variables-and-methods","Class (static) Variables & Methods","shockwave-curriculum\u002Flessons\u002Fch07-the-class-blueprint\u002F7.4-class-static-variables-and-methods",{"path":137,"title":138,"stem":139},"\u002Fshockwave-curriculum\u002Flessons\u002Fch08-constructors-and-this\u002F1-8.2-constructors-and-this","Constructors & \"this\"","shockwave-curriculum\u002Flessons\u002Fch08-constructors-and-this\u002F8.1-8.2-constructors-and-this",{"path":141,"title":142,"stem":143},"\u002Fshockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F1-array-creation-and-access","Array Creation and Access","shockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F9.1-array-creation-and-access",{"path":145,"title":146,"stem":147},"\u002Fshockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F2-arraylist-and-its-methods","ArrayList and its Methods","shockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F9.2-arraylist-and-its-methods",{"path":149,"title":150,"stem":151},"\u002Fshockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F3-optional-hashmap-dictionary-data-structure","HashMap (Dictionary) Data Structure","shockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F9.3-optional-hashmap-dictionary-data-structure",{"path":153,"title":154,"stem":155},"\u002Fshockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F4-array-traversals","Array Traversals","shockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F9.4-array-traversals",{"path":157,"title":158,"stem":159},"\u002Fshockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F5-implementing-array-algorithms","Implementing Array Algorithms","shockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F9.5-implementing-array-algorithms",{"path":161,"title":162,"stem":163},"\u002Fshockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F6-arraylist-traversals","ArrayList Traversals","shockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F9.6-arraylist-traversals",{"path":165,"title":166,"stem":167},"\u002Fshockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F7-implementing-arraylist-algorithms","Implementing ArrayList Algorithms","shockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F9.7-implementing-arraylist-algorithms",{"path":169,"title":170,"stem":171},"\u002Fshockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F8-using-text-files","Using Text Files","shockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F9.8-using-text-files",{"path":173,"title":174,"stem":175},"\u002Fshockwave-curriculum\u002Flessons\u002Fch10-2d-arrays\u002F1-2d-array-creation-and-access","2D Array Creation and Access","shockwave-curriculum\u002Flessons\u002Fch10-2d-arrays\u002F10.1-2d-array-creation-and-access",{"path":177,"title":178,"stem":179},"\u002Fshockwave-curriculum\u002Flessons\u002Fch10-2d-arrays\u002F2-2d-array-traversals-nested-loops","2D Array Traversals: Nested Loops","shockwave-curriculum\u002Flessons\u002Fch10-2d-arrays\u002F10.2-2d-array-traversals-nested-loops",{"path":181,"title":182,"stem":183},"\u002Fshockwave-curriculum\u002Flessons\u002Fch10-2d-arrays\u002F3-implementing-2d-array-algorithms","Implementing 2D Array Algorithms","shockwave-curriculum\u002Flessons\u002Fch10-2d-arrays\u002F10.3-implementing-2d-array-algorithms",{"path":185,"title":186,"stem":187},"\u002Fshockwave-curriculum\u002Flessons\u002Fch11-enums-named-choices\u002F11-enums-named-choices","Enums: Named Choices","shockwave-curriculum\u002Flessons\u002Fch11-enums-named-choices\u002F11-enums-named-choices",{"path":189,"title":190,"stem":191},"\u002Fshockwave-curriculum\u002Flessons\u002Fch12-exceptions-and-try-catch\u002F12-exceptions-and-try-catch","Exceptions & try\u002Fcatch","shockwave-curriculum\u002Flessons\u002Fch12-exceptions-and-try-catch\u002F12-exceptions-and-try-catch",{"path":193,"title":194,"stem":195},"\u002Fshockwave-curriculum\u002Flessons\u002Fch13-common-gotchas\u002F13-common-gotchas","Common Gotchas","shockwave-curriculum\u002Flessons\u002Fch13-common-gotchas\u002F13-common-gotchas",{"path":197,"title":198,"stem":199},"\u002Fshockwave-curriculum\u002Flessons\u002Fch14-why-design-patterns\u002F14-why-design-patterns","Why Design Patterns?","shockwave-curriculum\u002Flessons\u002Fch14-why-design-patterns\u002F14-why-design-patterns",{"path":201,"title":202,"stem":203},"\u002Fshockwave-curriculum\u002Flessons\u002Fch15-advanced-collections\u002F15-advanced-collections","Advanced Collections (Set\u002FQueue\u002FMap)","shockwave-curriculum\u002Flessons\u002Fch15-advanced-collections\u002F15-advanced-collections",{"path":205,"title":206,"stem":207},"\u002Fshockwave-curriculum\u002Flessons\u002Fch16-writing-your-own-generics\u002F16-writing-your-own-generics","Writing Your Own Generics","shockwave-curriculum\u002Flessons\u002Fch16-writing-your-own-generics\u002F16-writing-your-own-generics",{"path":209,"title":210,"stem":211},"\u002Fshockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F1-inheritance-superclass-subclass","Inheritance, Superclass, Subclass","shockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F17.1-inheritance-superclass-subclass",{"path":213,"title":214,"stem":215},"\u002Fshockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F2-inheritance-and-constructors","Inheritance and Constructors","shockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F17.2-inheritance-and-constructors",{"path":217,"title":218,"stem":219},"\u002Fshockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F3-inheritance-hierarchies","Inheritance Hierarchies","shockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F17.3-inheritance-hierarchies",{"path":221,"title":222,"stem":223},"\u002Fshockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F4-object-superclass","Object Superclass","shockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F17.4-object-superclass",{"path":225,"title":226,"stem":227},"\u002Fshockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F5-abstract-classes-and-methods","Abstract Classes and Methods","shockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F17.5-abstract-classes-and-methods",{"path":229,"title":230,"stem":231},"\u002Fshockwave-curriculum\u002Flessons\u002Fch18-polymorphism-many-forms\u002F1-overriding-methods","Overriding Methods","shockwave-curriculum\u002Flessons\u002Fch18-polymorphism-many-forms\u002F18.1-overriding-methods",{"path":233,"title":234,"stem":235},"\u002Fshockwave-curriculum\u002Flessons\u002Fch18-polymorphism-many-forms\u002F2-super-keyword","super Keyword","shockwave-curriculum\u002Flessons\u002Fch18-polymorphism-many-forms\u002F18.2-super-keyword",{"path":237,"title":238,"stem":239},"\u002Fshockwave-curriculum\u002Flessons\u002Fch18-polymorphism-many-forms\u002F3-polymorphism","Polymorphism","shockwave-curriculum\u002Flessons\u002Fch18-polymorphism-many-forms\u002F18.3-polymorphism",{"path":241,"title":242,"stem":243},"\u002Fshockwave-curriculum\u002Flessons\u002Fch19-interfaces-as-contracts\u002F19-interfaces-as-contracts","Interfaces as Contracts","shockwave-curriculum\u002Flessons\u002Fch19-interfaces-as-contracts\u002F19-interfaces-as-contracts",{"path":245,"title":246,"stem":247},"\u002Fshockwave-curriculum\u002Flessons\u002Fch19-interfaces-as-contracts\u002F1-lambdas-and-method-references","Lambdas & Method References","shockwave-curriculum\u002Flessons\u002Fch19-interfaces-as-contracts\u002F19.1-lambdas-and-method-references",{"path":249,"title":250,"stem":251},"\u002Fshockwave-curriculum\u002Flessons\u002Fch20-the-io-layer-pattern\u002F20-the-io-layer-pattern","The IO-Layer Pattern","shockwave-curriculum\u002Flessons\u002Fch20-the-io-layer-pattern\u002F20-the-io-layer-pattern",{"path":253,"title":254,"stem":255},"\u002Fshockwave-curriculum\u002Flessons\u002Fch21-static-factories\u002F21-static-factories","Static Factories","shockwave-curriculum\u002Flessons\u002Fch21-static-factories\u002F21-static-factories",{"path":257,"title":258,"stem":259},"\u002Fshockwave-curriculum\u002Flessons\u002Fch22-the-builder-pattern\u002F22-the-builder-pattern","The Builder Pattern","shockwave-curriculum\u002Flessons\u002Fch22-the-builder-pattern\u002F22-the-builder-pattern",{"path":261,"title":262,"stem":263},"\u002Fshockwave-curriculum\u002Flessons\u002Fch23-encapsulation-and-final\u002F1-scope-and-access","Access, final, and Immutability","shockwave-curriculum\u002Flessons\u002Fch23-encapsulation-and-final\u002F23.1-scope-and-access",{"path":265,"title":266,"stem":267},"\u002Fshockwave-curriculum\u002Flessons\u002Fch24-optional-avoiding-null-pointer-exceptions\u002F24-optional-avoiding-null-pointer-exceptions","Optional: Avoiding Null Pointer Exceptions","shockwave-curriculum\u002Flessons\u002Fch24-optional-avoiding-null-pointer-exceptions\u002F24-optional-avoiding-null-pointer-exceptions",{"path":269,"title":270,"stem":271},"\u002Fshockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F1-what-is-command-based-programming","What Is Command-Based Programming?","shockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F25.1-what-is-command-based-programming",{"path":273,"title":274,"stem":275},"\u002Fshockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F2-commands-and-command-compositions","Commands & Command Compositions","shockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F25.2-commands-and-command-compositions",{"path":277,"title":278,"stem":279},"\u002Fshockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F3-the-command-scheduler","The Command Scheduler","shockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F25.3-the-command-scheduler",{"path":281,"title":282,"stem":283},"\u002Fshockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F4-state-machines-logic","State Machines: Logic","shockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F25.4-state-machines-logic",{"path":285,"title":286,"stem":287},"\u002Fshockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F5-managing-transitions","Managing Transitions","shockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F25.5-managing-transitions",{"path":289,"title":290,"stem":291},"\u002Fshockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F6-binding-commands-to-triggers","Binding Commands to Triggers","shockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F25.6-binding-commands-to-triggers",{"path":293,"title":294,"stem":295},"\u002Fshockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F7-structuring-a-command-based-robot-project","Structuring a Command-Based Robot Project","shockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F25.7-structuring-a-command-based-robot-project",{"path":297,"title":298,"stem":299},"\u002Fshockwave-curriculum\u002Flessons\u002Fch26-architecture-takeaways\u002F26-architecture-takeaways","Architecture Takeaways","shockwave-curriculum\u002Flessons\u002Fch26-architecture-takeaways\u002F26-architecture-takeaways",{"path":301,"title":302,"stem":303},"\u002Fshockwave-curriculum\u002Flessons\u002Fch27-program-design-and-abstraction\u002F1-abstraction-and-program-design","Abstraction and Program Design","shockwave-curriculum\u002Flessons\u002Fch27-program-design-and-abstraction\u002F27.1-abstraction-and-program-design",{"path":305,"title":306,"stem":307},"\u002Fshockwave-curriculum\u002Flessons\u002Fch27-program-design-and-abstraction\u002F2-impact-of-program-design","Impact of Program Design","shockwave-curriculum\u002Flessons\u002Fch27-program-design-and-abstraction\u002F27.2-impact-of-program-design",{"path":309,"title":310,"stem":311},"\u002Fshockwave-curriculum\u002Flessons\u002Fch28-algorithms-searching-sorting-recursion\u002F1-searching-algorithms","Searching Algorithms","shockwave-curriculum\u002Flessons\u002Fch28-algorithms-searching-sorting-recursion\u002F28.1-searching-algorithms",{"path":313,"title":314,"stem":315},"\u002Fshockwave-curriculum\u002Flessons\u002Fch28-algorithms-searching-sorting-recursion\u002F2-sorting-algorithms","Sorting Algorithms","shockwave-curriculum\u002Flessons\u002Fch28-algorithms-searching-sorting-recursion\u002F28.2-sorting-algorithms",{"path":317,"title":318,"stem":319},"\u002Fshockwave-curriculum\u002Flessons\u002Fch28-algorithms-searching-sorting-recursion\u002F3-recursion","Recursion","shockwave-curriculum\u002Flessons\u002Fch28-algorithms-searching-sorting-recursion\u002F28.3-recursion",{"path":321,"title":322,"stem":323},"\u002Fshockwave-curriculum\u002Flessons\u002Fch28-algorithms-searching-sorting-recursion\u002F4-recursive-searching-and-sorting","Recursive Searching and Sorting","shockwave-curriculum\u002Flessons\u002Fch28-algorithms-searching-sorting-recursion\u002F28.4-recursive-searching-and-sorting",{"path":325,"title":326,"stem":327},"\u002Fshockwave-curriculum\u002Flessons\u002Fch29-git-and-github-basics\u002F1-coming-soon","Git & GitHub Basics — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch29-git-and-github-basics\u002F29.1-coming-soon",{"path":329,"title":330,"stem":331},"\u002Fshockwave-curriculum\u002Flessons\u002Fch30-git-history-and-merging\u002F1-coming-soon","Git — History & Merging — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch30-git-history-and-merging\u002F30.1-coming-soon",{"path":333,"title":334,"stem":335},"\u002Fshockwave-curriculum\u002Flessons\u002Fch31-dev-environment-and-tooling\u002F1-coming-soon","Dev Environment & Tooling — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch31-dev-environment-and-tooling\u002F31.1-coming-soon",{"path":337,"title":338,"stem":339},"\u002Fshockwave-curriculum\u002Flessons\u002Fch32-unit-testing\u002F1-coming-soon","Unit Testing — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch32-unit-testing\u002F32.1-coming-soon",{"path":341,"title":342,"stem":343},"\u002Fshockwave-curriculum\u002Flessons\u002Fch33-advantagekit-autologging\u002F1-coming-soon","AdvantageKit — AutoLogging — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch33-advantagekit-autologging\u002F33.1-coming-soon",{"path":345,"title":346,"stem":347},"\u002Fshockwave-curriculum\u002Flessons\u002Fch34-log-replay\u002F1-coming-soon","Log Replay — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch34-log-replay\u002F34.1-coming-soon",{"path":349,"title":350,"stem":351},"\u002Fshockwave-curriculum\u002Flessons\u002Fch35-advantagescope-i-visualization\u002F1-coming-soon","AdvantageScope I: Visualization — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch35-advantagescope-i-visualization\u002F35.1-coming-soon",{"path":353,"title":354,"stem":355},"\u002Fshockwave-curriculum\u002Flessons\u002Fch36-advantagescope-ii-custom-3d-assets\u002F1-coming-soon","AdvantageScope II: Custom 3D Assets — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch36-advantagescope-ii-custom-3d-assets\u002F36.1-coming-soon",{"path":357,"title":358,"stem":359},"\u002Fshockwave-curriculum\u002Flessons\u002Fch37-autonomous-i\u002F1-coming-soon","Autonomous I — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch37-autonomous-i\u002F37.1-coming-soon",{"path":361,"title":362,"stem":363},"\u002Fshockwave-curriculum\u002Flessons\u002Fch38-autonomous-ii-pathplanner-and-trajectories\u002F1-coming-soon","Autonomous II: PathPlanner & Trajectories — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch38-autonomous-ii-pathplanner-and-trajectories\u002F38.1-coming-soon",{"path":365,"title":366,"stem":367},"\u002Fshockwave-curriculum\u002Flessons\u002Fch39-control-fundamentals\u002F1-coming-soon","Control Fundamentals — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch39-control-fundamentals\u002F39.1-coming-soon",{"path":369,"title":370,"stem":371},"\u002Fshockwave-curriculum\u002Flessons\u002Fch40-motion-profiles\u002F1-coming-soon","Motion Profiles — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch40-motion-profiles\u002F40.1-coming-soon",{"path":373,"title":374,"stem":375},"\u002Fshockwave-curriculum\u002Flessons\u002Fch41-hardware-fundamentals\u002F1-coming-soon","Hardware Fundamentals — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch41-hardware-fundamentals\u002F41.1-coming-soon",{"path":377,"title":378,"stem":379},"\u002Fshockwave-curriculum\u002Flessons\u002Fch42-photonvision\u002F1-coming-soon","PhotonVision — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch42-photonvision\u002F42.1-coming-soon",{"path":381,"title":382,"stem":383},"\u002Fshockwave-curriculum\u002Flessons\u002Fch43-apriltags-and-pose\u002F1-coming-soon","AprilTags & Pose — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch43-apriltags-and-pose\u002F43.1-coming-soon",{"path":385,"title":386,"stem":387},"\u002Fshockwave-curriculum\u002Flessons\u002Fch44-subsystems-i\u002F1-coming-soon","Subsystems I — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch44-subsystems-i\u002F44.1-coming-soon",{"path":389,"title":390,"stem":391},"\u002Fshockwave-curriculum\u002Flessons\u002Fch45-subsystems-ii-advanced\u002F1-coming-soon","Subsystems II — Advanced — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch45-subsystems-ii-advanced\u002F45.1-coming-soon",{"path":393,"title":394,"stem":395},"\u002Fshockwave-curriculum\u002Flessons\u002Fch46-team-utilities-i\u002F1-coming-soon","Team Utilities I — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch46-team-utilities-i\u002F46.1-coming-soon",{"path":397,"title":398,"stem":399},"\u002Fshockwave-curriculum\u002Flessons\u002Fch47-field-constants\u002F1-coming-soon","Field Constants — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch47-field-constants\u002F47.1-coming-soon",{"path":401,"title":402,"stem":403},"\u002Fshockwave-curriculum\u002Flessons\u002Fch48-troubleshooting-i-runtime-debug\u002F1-coming-soon","Troubleshooting I — Runtime Debug — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch48-troubleshooting-i-runtime-debug\u002F48.1-coming-soon",{"path":405,"title":406,"stem":407},"\u002Fshockwave-curriculum\u002Flessons\u002Fch49-troubleshooting-ii-can-and-sim\u002F1-coming-soon","Troubleshooting II: CAN & Sim — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch49-troubleshooting-ii-can-and-sim\u002F49.1-coming-soon",{"path":409,"title":410,"stem":411},"\u002Fshockwave-curriculum\u002Flessons\u002Fch50-vendor-libraries-talonfx\u002F1-coming-soon","Vendor Libraries: TalonFX — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch50-vendor-libraries-talonfx\u002F50.1-coming-soon",{"path":413,"title":414,"stem":415},"\u002Fshockwave-curriculum\u002Flessons\u002Fch51-robot-alerts\u002F1-coming-soon","Robot Alerts — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch51-robot-alerts\u002F51.1-coming-soon",{"path":417,"title":418,"stem":419},"\u002Fshockwave-curriculum\u002Flessons\u002Fch52-wpilib-commands\u002F1-coming-soon","WPILib Commands — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch52-wpilib-commands\u002F52.1-coming-soon",{"path":421,"title":422,"stem":423},"\u002Fshockwave-curriculum\u002Flessons\u002Fch53-wpilib-geometry\u002F1-coming-soon","WPILib Geometry — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch53-wpilib-geometry\u002F53.1-coming-soon",{"path":425,"title":426,"stem":427},"\u002Fshockwave-curriculum\u002Flessons\u002Fch54-networktables\u002F1-coming-soon","NetworkTables — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch54-networktables\u002F54.1-coming-soon",{"path":429,"title":430,"stem":431},"\u002Fshockwave-curriculum\u002Flessons\u002Fch55-command-scheduler\u002F1-coming-soon","Command Scheduler — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch55-command-scheduler\u002F55.1-coming-soon",{"path":433,"title":434,"stem":435},"\u002Fshockwave-curriculum\u002Flessons\u002Fch56-wpilib-timers\u002F1-coming-soon","WPILib Timers — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch56-wpilib-timers\u002F56.1-coming-soon",{"path":437,"title":438,"stem":439},"\u002Fshockwave-curriculum\u002Flessons\u002Fch57-wpilib-triggers\u002F1-coming-soon","WPILib Triggers — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch57-wpilib-triggers\u002F57.1-coming-soon",{"path":441,"title":442,"stem":443},"\u002Fshockwave-curriculum\u002Flessons\u002Fch58-vendor-units-and-conversions\u002F1-coming-soon","Vendor Units & Conversions — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch58-vendor-units-and-conversions\u002F58.1-coming-soon",[445,449,453,457,461,465,469,473,477,481,485,489,493,497,501,505,509,513,517,521,525,529,533,537,541,545,549,553,557,561,565,569,573,577,581,585,589,593,597,601,605,609,613,617,621,625,629,633,637,641,645,649,653,657,661,665,669,673,677,681,685,689,693,697,701,705,709,713,717,721,725,729,733,737,741,745,749],{"path":446,"title":447,"stem":448},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch01-why-java-for-frc\u002F2-intro-to-algorithms-programming-and-compilers","Intro to Algorithms, Programming and Compilers — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch01-why-java-for-frc\u002F1.2-intro-to-algorithms-programming-and-compilers",{"path":450,"title":451,"stem":452},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F1-variables-and-data-types","Variables & Data Types — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F2.1-variables-and-data-types",{"path":454,"title":455,"stem":456},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F2-expressions-and-output","Expressions & Output — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F2.2-expressions-and-output",{"path":458,"title":459,"stem":460},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F3-assignment-and-input","Assignment & Input — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F2.3-assignment-and-input",{"path":462,"title":463,"stem":464},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F4-casting-and-ranges-of-values","Casting & Ranges of Values — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F2.4-casting-and-ranges-of-values",{"path":466,"title":467,"stem":468},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F5-compound-assignment-operators","Compound Assignment Operators — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F2.5-compound-assignment-operators",{"path":470,"title":471,"stem":472},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch03-apis-libraries-and-documentation\u002F1-apis-and-libraries","APIs and Libraries — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch03-apis-libraries-and-documentation\u002F3.1-apis-and-libraries",{"path":474,"title":475,"stem":476},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch03-apis-libraries-and-documentation\u002F2-documentation-with-comments-and-preconditions","Documentation with Comments and Preconditions — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch03-apis-libraries-and-documentation\u002F3.2-documentation-with-comments-and-preconditions",{"path":478,"title":479,"stem":480},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch03-apis-libraries-and-documentation\u002F3-packages-and-imports","Packages & Imports — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch03-apis-libraries-and-documentation\u002F3.3-packages-and-imports",{"path":482,"title":483,"stem":484},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F1-methods-signatures-and-parameters","Methods, Signatures & Parameters — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F4.1-methods-signatures-and-parameters",{"path":486,"title":487,"stem":488},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F2-calling-class-methods","Calling Class Methods — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F4.2-calling-class-methods",{"path":490,"title":491,"stem":492},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F3-using-the-math-class","Using the Math Class — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F4.3-using-the-math-class",{"path":494,"title":495,"stem":496},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F4-objects-instances-of-classes","Objects — Instances of Classes — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F4.4-objects-instances-of-classes",{"path":498,"title":499,"stem":500},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F5-creating-and-initializing-objects-constructors","Creating & Initializing Objects: Constructors — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F4.5-creating-and-initializing-objects-constructors",{"path":502,"title":503,"stem":504},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F6-calling-instance-methods","Calling Instance Methods — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F4.6-calling-instance-methods",{"path":506,"title":507,"stem":508},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F1-5.2-if-statements-and-for-loops","if Statements & For Loops — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.1-5.2-if-statements-and-for-loops",{"path":510,"title":511,"stem":512},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F10-nested-iteration","Nested Iteration — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.10-nested-iteration",{"path":514,"title":515,"stem":516},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F11-informal-runtime-analysis-of-loops","Informal Runtime Analysis of Loops — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.11-informal-runtime-analysis-of-loops",{"path":518,"title":519,"stem":520},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F12-switch-statements-and-expressions","switch Statements and Expressions — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.12-switch-statements-and-expressions",{"path":522,"title":523,"stem":524},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F3-algorithms-with-selection-and-repetition","Algorithms with Selection and Repetition — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.3-algorithms-with-selection-and-repetition",{"path":526,"title":527,"stem":528},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F4-boolean-expressions","Boolean Expressions — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.4-boolean-expressions",{"path":530,"title":531,"stem":532},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5-nested-if-statements","Nested if Statements — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.5-nested-if-statements",{"path":534,"title":535,"stem":536},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F6-compound-boolean-expressions","Compound Boolean Expressions — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.6-compound-boolean-expressions",{"path":538,"title":539,"stem":540},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F7-comparing-boolean-expressions-de-morgans-laws","Comparing Boolean Expressions (De Morgan's Laws) — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.7-comparing-boolean-expressions-de-morgans-laws",{"path":542,"title":543,"stem":544},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F8-while-loops","While Loops — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.8-while-loops",{"path":546,"title":547,"stem":548},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F9-implementing-selection-and-iteration-algorithms","Implementing Selection and Iteration Algorithms — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.9-implementing-selection-and-iteration-algorithms",{"path":550,"title":551,"stem":552},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch06-strings\u002F1-strings","Strings — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch06-strings\u002F6.1-strings",{"path":554,"title":555,"stem":556},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch06-strings\u002F2-string-algorithms","String Algorithms — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch06-strings\u002F6.2-string-algorithms",{"path":558,"title":559,"stem":560},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch07-the-class-blueprint\u002F1-anatomy-of-a-java-class","Anatomy of a Java Class — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch07-the-class-blueprint\u002F7.1-anatomy-of-a-java-class",{"path":562,"title":563,"stem":564},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch07-the-class-blueprint\u002F2-methods-how-to-write-them","Methods: How to Write Them — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch07-the-class-blueprint\u002F7.2-methods-how-to-write-them",{"path":566,"title":567,"stem":568},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch07-the-class-blueprint\u002F3-methods-passing-and-returning-references-of-an-object","Methods: Passing & Returning References of an Object — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch07-the-class-blueprint\u002F7.3-methods-passing-and-returning-references-of-an-object",{"path":570,"title":571,"stem":572},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch07-the-class-blueprint\u002F4-class-static-variables-and-methods","Class (static) Variables & Methods — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch07-the-class-blueprint\u002F7.4-class-static-variables-and-methods",{"path":574,"title":575,"stem":576},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch08-constructors-and-this\u002F1-8.2-constructors-and-this","Constructors & \"this\" — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch08-constructors-and-this\u002F8.1-8.2-constructors-and-this",{"path":578,"title":579,"stem":580},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F1-array-creation-and-access","Array Creation and Access — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F9.1-array-creation-and-access",{"path":582,"title":583,"stem":584},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F2-arraylist-and-its-methods","ArrayList and its Methods — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F9.2-arraylist-and-its-methods",{"path":586,"title":587,"stem":588},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F3-optional-hashmap-dictionary-data-structure","HashMap (Dictionary) Data Structure — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F9.3-optional-hashmap-dictionary-data-structure",{"path":590,"title":591,"stem":592},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F4-array-traversals","Array Traversals — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F9.4-array-traversals",{"path":594,"title":595,"stem":596},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F5-implementing-array-algorithms","Implementing Array Algorithms — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F9.5-implementing-array-algorithms",{"path":598,"title":599,"stem":600},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F6-arraylist-traversals","ArrayList Traversals — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F9.6-arraylist-traversals",{"path":602,"title":603,"stem":604},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F7-implementing-arraylist-algorithms","Implementing ArrayList Algorithms — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F9.7-implementing-arraylist-algorithms",{"path":606,"title":607,"stem":608},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F8-using-text-files","Using Text Files — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F9.8-using-text-files",{"path":610,"title":611,"stem":612},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch10-2d-arrays\u002F1-2d-array-creation-and-access","2D Array Creation and Access — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch10-2d-arrays\u002F10.1-2d-array-creation-and-access",{"path":614,"title":615,"stem":616},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch10-2d-arrays\u002F2-2d-array-traversals-nested-loops","2D Array Traversals: Nested Loops — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch10-2d-arrays\u002F10.2-2d-array-traversals-nested-loops",{"path":618,"title":619,"stem":620},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch10-2d-arrays\u002F3-implementing-2d-array-algorithms","Implementing 2D Array Algorithms — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch10-2d-arrays\u002F10.3-implementing-2d-array-algorithms",{"path":622,"title":623,"stem":624},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch11-enums-named-choices\u002F11-enums-named-choices","Enums: Named Choices — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch11-enums-named-choices\u002F11-enums-named-choices",{"path":626,"title":627,"stem":628},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch12-exceptions-and-try-catch\u002F12-exceptions-and-try-catch","Exceptions & try\u002Fcatch — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch12-exceptions-and-try-catch\u002F12-exceptions-and-try-catch",{"path":630,"title":631,"stem":632},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch13-common-gotchas\u002F13-common-gotchas","Common Gotchas — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch13-common-gotchas\u002F13-common-gotchas",{"path":634,"title":635,"stem":636},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch15-advanced-collections\u002F15-advanced-collections","Advanced Collections (Set\u002FQueue\u002FMap) — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch15-advanced-collections\u002F15-advanced-collections",{"path":638,"title":639,"stem":640},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch16-writing-your-own-generics\u002F16-writing-your-own-generics","Writing Your Own Generics — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch16-writing-your-own-generics\u002F16-writing-your-own-generics",{"path":642,"title":643,"stem":644},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F1-inheritance-superclass-subclass","Inheritance, Superclass, Subclass — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F17.1-inheritance-superclass-subclass",{"path":646,"title":647,"stem":648},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F2-inheritance-and-constructors","Inheritance and Constructors — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F17.2-inheritance-and-constructors",{"path":650,"title":651,"stem":652},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F3-inheritance-hierarchies","Inheritance Hierarchies — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F17.3-inheritance-hierarchies",{"path":654,"title":655,"stem":656},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F4-object-superclass","Object Superclass — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F17.4-object-superclass",{"path":658,"title":659,"stem":660},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F5-abstract-classes-and-methods","Abstract Classes and Methods — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F17.5-abstract-classes-and-methods",{"path":662,"title":663,"stem":664},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch18-polymorphism-many-forms\u002F1-overriding-methods","Overriding Methods — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch18-polymorphism-many-forms\u002F18.1-overriding-methods",{"path":666,"title":667,"stem":668},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch18-polymorphism-many-forms\u002F2-super-keyword","super Keyword — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch18-polymorphism-many-forms\u002F18.2-super-keyword",{"path":670,"title":671,"stem":672},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch18-polymorphism-many-forms\u002F3-polymorphism","Polymorphism — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch18-polymorphism-many-forms\u002F18.3-polymorphism",{"path":674,"title":675,"stem":676},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch19-interfaces-as-contracts\u002F19-interfaces-as-contracts","Interfaces as Contracts — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch19-interfaces-as-contracts\u002F19-interfaces-as-contracts",{"path":678,"title":679,"stem":680},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch19-interfaces-as-contracts\u002F1-lambdas-and-method-references","Lambdas & Method References — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch19-interfaces-as-contracts\u002F19.1-lambdas-and-method-references",{"path":682,"title":683,"stem":684},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch20-the-io-layer-pattern\u002F20-the-io-layer-pattern","The IO-Layer Pattern — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch20-the-io-layer-pattern\u002F20-the-io-layer-pattern",{"path":686,"title":687,"stem":688},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch21-static-factories\u002F21-static-factories","Static Factories — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch21-static-factories\u002F21-static-factories",{"path":690,"title":691,"stem":692},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch22-the-builder-pattern\u002F22-the-builder-pattern","The Builder Pattern — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch22-the-builder-pattern\u002F22-the-builder-pattern",{"path":694,"title":695,"stem":696},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch23-encapsulation-and-final\u002F1-scope-and-access","Access, final, and Immutability — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch23-encapsulation-and-final\u002F23.1-scope-and-access",{"path":698,"title":699,"stem":700},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch24-optional-avoiding-null-pointer-exceptions\u002F24-optional-avoiding-null-pointer-exceptions","Optional: Avoiding Null Pointer Exceptions — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch24-optional-avoiding-null-pointer-exceptions\u002F24-optional-avoiding-null-pointer-exceptions",{"path":702,"title":703,"stem":704},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F1-what-is-command-based-programming","What Is Command-Based Programming? — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F25.1-what-is-command-based-programming",{"path":706,"title":707,"stem":708},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F2-commands-and-command-compositions","Commands & Command Compositions — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F25.2-commands-and-command-compositions",{"path":710,"title":711,"stem":712},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F3-the-command-scheduler","The Command Scheduler — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F25.3-the-command-scheduler",{"path":714,"title":715,"stem":716},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F4-state-machines-logic","State Machines: Logic — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F25.4-state-machines-logic",{"path":718,"title":719,"stem":720},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F5-managing-transitions","Managing Transitions — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F25.5-managing-transitions",{"path":722,"title":723,"stem":724},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F6-binding-commands-to-triggers","Binding Commands to Triggers — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F25.6-binding-commands-to-triggers",{"path":726,"title":727,"stem":728},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F7-structuring-a-command-based-robot-project","Structuring a Command-Based Robot Project — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F25.7-structuring-a-command-based-robot-project",{"path":730,"title":731,"stem":732},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch26-architecture-takeaways\u002F26-architecture-takeaways","Architecture Takeaways — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch26-architecture-takeaways\u002F26-architecture-takeaways",{"path":734,"title":735,"stem":736},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch27-program-design-and-abstraction\u002F1-abstraction-and-program-design","Abstraction and Program Design — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch27-program-design-and-abstraction\u002F27.1-abstraction-and-program-design",{"path":738,"title":739,"stem":740},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch28-algorithms-searching-sorting-recursion\u002F1-searching-algorithms","Searching Algorithms — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch28-algorithms-searching-sorting-recursion\u002F28.1-searching-algorithms",{"path":742,"title":743,"stem":744},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch28-algorithms-searching-sorting-recursion\u002F2-sorting-algorithms","Sorting Algorithms — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch28-algorithms-searching-sorting-recursion\u002F28.2-sorting-algorithms",{"path":746,"title":747,"stem":748},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch28-algorithms-searching-sorting-recursion\u002F3-recursion","Recursion — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch28-algorithms-searching-sorting-recursion\u002F28.3-recursion",{"path":750,"title":751,"stem":752},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch28-algorithms-searching-sorting-recursion\u002F4-recursive-searching-and-sorting","Recursive Searching and Sorting — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch28-algorithms-searching-sorting-recursion\u002F28.4-recursive-searching-and-sorting",[754,758,762,766,770,774,778,782,786,790,794,798,802,806,810,814,818,822,826,830,834,838,842,846,850,854,858,862,866,870,874,878,882,886,890,894,898,902,906,910,914,918,922,926,930,934,938,942,946,950,954,958,962,966,970,974,978,982,986,990,994,998,1002,1006,1010,1014,1018,1022,1026,1030,1034,1038,1042,1046,1050,1054,1058,1062,1066],{"path":755,"title":756,"stem":757},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch01-why-java-for-frc\u002F2-intro-to-algorithms-programming-and-compilers","Intro to Algorithms, Programming and Compilers — Exercises","shockwave-curriculum\u002Fexercises\u002Fch01-why-java-for-frc\u002F1.2-intro-to-algorithms-programming-and-compilers",{"path":759,"title":760,"stem":761},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F1-variables-and-data-types","Variables & Data Types — Exercises","shockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F2.1-variables-and-data-types",{"path":763,"title":764,"stem":765},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F2-expressions-and-output","Expressions & Output — Exercises","shockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F2.2-expressions-and-output",{"path":767,"title":768,"stem":769},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F3-assignment-and-input","Assignment & Input — Exercises","shockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F2.3-assignment-and-input",{"path":771,"title":772,"stem":773},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F4-casting-and-ranges-of-values","Casting & Ranges of Values — Exercises","shockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F2.4-casting-and-ranges-of-values",{"path":775,"title":776,"stem":777},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F5-compound-assignment-operators","Compound Assignment Operators — Exercises","shockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F2.5-compound-assignment-operators",{"path":779,"title":780,"stem":781},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch03-apis-libraries-and-documentation\u002F1-apis-and-libraries","APIs and Libraries — Exercises","shockwave-curriculum\u002Fexercises\u002Fch03-apis-libraries-and-documentation\u002F3.1-apis-and-libraries",{"path":783,"title":784,"stem":785},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch03-apis-libraries-and-documentation\u002F2-documentation-with-comments-and-preconditions","Documentation with Comments and Preconditions — Exercises","shockwave-curriculum\u002Fexercises\u002Fch03-apis-libraries-and-documentation\u002F3.2-documentation-with-comments-and-preconditions",{"path":787,"title":788,"stem":789},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch03-apis-libraries-and-documentation\u002F3-packages-and-imports","Packages & Imports — Exercises","shockwave-curriculum\u002Fexercises\u002Fch03-apis-libraries-and-documentation\u002F3.3-packages-and-imports",{"path":791,"title":792,"stem":793},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F1-methods-signatures-and-parameters","Methods, Signatures & Parameters — Exercises","shockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F4.1-methods-signatures-and-parameters",{"path":795,"title":796,"stem":797},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F2-calling-class-methods","Calling Class Methods — Exercises","shockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F4.2-calling-class-methods",{"path":799,"title":800,"stem":801},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F3-using-the-math-class","Using the Math Class — Exercises","shockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F4.3-using-the-math-class",{"path":803,"title":804,"stem":805},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F4-objects-instances-of-classes","Objects — Instances of Classes — Exercises","shockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F4.4-objects-instances-of-classes",{"path":807,"title":808,"stem":809},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F5-creating-and-initializing-objects-constructors","Creating & Initializing Objects: Constructors — Exercises","shockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F4.5-creating-and-initializing-objects-constructors",{"path":811,"title":812,"stem":813},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F6-calling-instance-methods","Calling Instance Methods — Exercises","shockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F4.6-calling-instance-methods",{"path":815,"title":816,"stem":817},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F1-5.2-if-statements-and-for-loops","if Statements & For Loops — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.1-5.2-if-statements-and-for-loops",{"path":819,"title":820,"stem":821},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F10-nested-iteration","Nested Iteration — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.10-nested-iteration",{"path":823,"title":824,"stem":825},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F11-informal-runtime-analysis-of-loops","Informal Runtime Analysis of Loops — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.11-informal-runtime-analysis-of-loops",{"path":827,"title":828,"stem":829},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F12-switch-statements-and-expressions","switch Statements and Expressions — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.12-switch-statements-and-expressions",{"path":831,"title":832,"stem":833},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F3-algorithms-with-selection-and-repetition","Algorithms with Selection and Repetition — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.3-algorithms-with-selection-and-repetition",{"path":835,"title":836,"stem":837},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F4-boolean-expressions","Boolean Expressions — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.4-boolean-expressions",{"path":839,"title":840,"stem":841},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5-nested-if-statements","Nested if Statements — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.5-nested-if-statements",{"path":843,"title":844,"stem":845},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F6-compound-boolean-expressions","Compound Boolean Expressions — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.6-compound-boolean-expressions",{"path":847,"title":848,"stem":849},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F7-comparing-boolean-expressions-de-morgans-laws","Comparing Boolean Expressions (De Morgan's Laws) — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.7-comparing-boolean-expressions-de-morgans-laws",{"path":851,"title":852,"stem":853},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F8-while-loops","While Loops — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.8-while-loops",{"path":855,"title":856,"stem":857},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F9-implementing-selection-and-iteration-algorithms","Implementing Selection and Iteration Algorithms — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.9-implementing-selection-and-iteration-algorithms",{"path":859,"title":860,"stem":861},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch06-strings\u002F1-strings","Strings — Exercises","shockwave-curriculum\u002Fexercises\u002Fch06-strings\u002F6.1-strings",{"path":863,"title":864,"stem":865},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch06-strings\u002F2-string-algorithms","String Algorithms — Exercises","shockwave-curriculum\u002Fexercises\u002Fch06-strings\u002F6.2-string-algorithms",{"path":867,"title":868,"stem":869},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch07-the-class-blueprint\u002F1-anatomy-of-a-java-class","Anatomy of a Java Class — Exercises","shockwave-curriculum\u002Fexercises\u002Fch07-the-class-blueprint\u002F7.1-anatomy-of-a-java-class",{"path":871,"title":872,"stem":873},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch07-the-class-blueprint\u002F2-methods-how-to-write-them","Methods: How to Write Them — Exercises","shockwave-curriculum\u002Fexercises\u002Fch07-the-class-blueprint\u002F7.2-methods-how-to-write-them",{"path":875,"title":876,"stem":877},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch07-the-class-blueprint\u002F3-methods-passing-and-returning-references-of-an-object","Methods: Passing & Returning References of an Object — Exercises","shockwave-curriculum\u002Fexercises\u002Fch07-the-class-blueprint\u002F7.3-methods-passing-and-returning-references-of-an-object",{"path":879,"title":880,"stem":881},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch07-the-class-blueprint\u002F4-class-static-variables-and-methods","Class (static) Variables & Methods — Exercises","shockwave-curriculum\u002Fexercises\u002Fch07-the-class-blueprint\u002F7.4-class-static-variables-and-methods",{"path":883,"title":884,"stem":885},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch08-constructors-and-this\u002F1-8.2-constructors-and-this","Constructors & \"this\" — Exercises","shockwave-curriculum\u002Fexercises\u002Fch08-constructors-and-this\u002F8.1-8.2-constructors-and-this",{"path":887,"title":888,"stem":889},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F1-array-creation-and-access","Array Creation and Access — Exercises","shockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F9.1-array-creation-and-access",{"path":891,"title":892,"stem":893},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F2-arraylist-and-its-methods","ArrayList and its Methods — Exercises","shockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F9.2-arraylist-and-its-methods",{"path":895,"title":896,"stem":897},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F3-optional-hashmap-dictionary-data-structure","HashMap (Dictionary) Data Structure — Exercises","shockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F9.3-optional-hashmap-dictionary-data-structure",{"path":899,"title":900,"stem":901},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F4-array-traversals","Array Traversals — Exercises","shockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F9.4-array-traversals",{"path":903,"title":904,"stem":905},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F5-implementing-array-algorithms","Implementing Array Algorithms — Exercises","shockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F9.5-implementing-array-algorithms",{"path":907,"title":908,"stem":909},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F6-arraylist-traversals","ArrayList Traversals — Exercises","shockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F9.6-arraylist-traversals",{"path":911,"title":912,"stem":913},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F7-implementing-arraylist-algorithms","Implementing ArrayList Algorithms — Exercises","shockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F9.7-implementing-arraylist-algorithms",{"path":915,"title":916,"stem":917},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F8-using-text-files","Using Text Files — Exercises","shockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F9.8-using-text-files",{"path":919,"title":920,"stem":921},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch10-2d-arrays\u002F1-2d-array-creation-and-access","2D Array Creation and Access — Exercises","shockwave-curriculum\u002Fexercises\u002Fch10-2d-arrays\u002F10.1-2d-array-creation-and-access",{"path":923,"title":924,"stem":925},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch10-2d-arrays\u002F2-2d-array-traversals-nested-loops","2D Array Traversals: Nested Loops — Exercises","shockwave-curriculum\u002Fexercises\u002Fch10-2d-arrays\u002F10.2-2d-array-traversals-nested-loops",{"path":927,"title":928,"stem":929},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch10-2d-arrays\u002F3-implementing-2d-array-algorithms","Implementing 2D Array Algorithms — Exercises","shockwave-curriculum\u002Fexercises\u002Fch10-2d-arrays\u002F10.3-implementing-2d-array-algorithms",{"path":931,"title":932,"stem":933},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch11-enums-named-choices\u002F11-enums-named-choices","Enums: Named Choices — Exercises","shockwave-curriculum\u002Fexercises\u002Fch11-enums-named-choices\u002F11-enums-named-choices",{"path":935,"title":936,"stem":937},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch12-exceptions-and-try-catch\u002F12-exceptions-and-try-catch","Exceptions & try\u002Fcatch — Exercises","shockwave-curriculum\u002Fexercises\u002Fch12-exceptions-and-try-catch\u002F12-exceptions-and-try-catch",{"path":939,"title":940,"stem":941},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch13-common-gotchas\u002F13-common-gotchas","Common Gotchas — Exercises","shockwave-curriculum\u002Fexercises\u002Fch13-common-gotchas\u002F13-common-gotchas",{"path":943,"title":944,"stem":945},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch14-why-design-patterns\u002F14-why-design-patterns","Why Design Patterns? — Exercises","shockwave-curriculum\u002Fexercises\u002Fch14-why-design-patterns\u002F14-why-design-patterns",{"path":947,"title":948,"stem":949},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch15-advanced-collections\u002F15-advanced-collections","Advanced Collections (Set\u002FQueue\u002FMap) — Exercises","shockwave-curriculum\u002Fexercises\u002Fch15-advanced-collections\u002F15-advanced-collections",{"path":951,"title":952,"stem":953},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch16-writing-your-own-generics\u002F16-writing-your-own-generics","Writing Your Own Generics — Exercises","shockwave-curriculum\u002Fexercises\u002Fch16-writing-your-own-generics\u002F16-writing-your-own-generics",{"path":955,"title":956,"stem":957},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F1-inheritance-superclass-subclass","Inheritance, Superclass, Subclass — Exercises","shockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F17.1-inheritance-superclass-subclass",{"path":959,"title":960,"stem":961},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F2-inheritance-and-constructors","Inheritance and Constructors — Exercises","shockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F17.2-inheritance-and-constructors",{"path":963,"title":964,"stem":965},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F3-inheritance-hierarchies","Inheritance Hierarchies — Exercises","shockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F17.3-inheritance-hierarchies",{"path":967,"title":968,"stem":969},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F4-object-superclass","Object Superclass — Exercises","shockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F17.4-object-superclass",{"path":971,"title":972,"stem":973},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F5-abstract-classes-and-methods","Abstract Classes and Methods — Exercises","shockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F17.5-abstract-classes-and-methods",{"path":975,"title":976,"stem":977},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch18-polymorphism-many-forms\u002F1-overriding-methods","Overriding Methods — Exercises","shockwave-curriculum\u002Fexercises\u002Fch18-polymorphism-many-forms\u002F18.1-overriding-methods",{"path":979,"title":980,"stem":981},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch18-polymorphism-many-forms\u002F2-super-keyword","super Keyword — Exercises","shockwave-curriculum\u002Fexercises\u002Fch18-polymorphism-many-forms\u002F18.2-super-keyword",{"path":983,"title":984,"stem":985},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch18-polymorphism-many-forms\u002F3-polymorphism","Polymorphism — Exercises","shockwave-curriculum\u002Fexercises\u002Fch18-polymorphism-many-forms\u002F18.3-polymorphism",{"path":987,"title":988,"stem":989},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch19-interfaces-as-contracts\u002F19-interfaces-as-contracts","Interfaces as Contracts — Exercises","shockwave-curriculum\u002Fexercises\u002Fch19-interfaces-as-contracts\u002F19-interfaces-as-contracts",{"path":991,"title":992,"stem":993},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch19-interfaces-as-contracts\u002F1-lambdas-and-method-references","Lambdas & Method References — Exercises","shockwave-curriculum\u002Fexercises\u002Fch19-interfaces-as-contracts\u002F19.1-lambdas-and-method-references",{"path":995,"title":996,"stem":997},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch20-the-io-layer-pattern\u002F20-the-io-layer-pattern","The IO-Layer Pattern — Exercises","shockwave-curriculum\u002Fexercises\u002Fch20-the-io-layer-pattern\u002F20-the-io-layer-pattern",{"path":999,"title":1000,"stem":1001},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch21-static-factories\u002F21-static-factories","Static Factories — Exercises","shockwave-curriculum\u002Fexercises\u002Fch21-static-factories\u002F21-static-factories",{"path":1003,"title":1004,"stem":1005},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch22-the-builder-pattern\u002F22-the-builder-pattern","The Builder Pattern — Exercises","shockwave-curriculum\u002Fexercises\u002Fch22-the-builder-pattern\u002F22-the-builder-pattern",{"path":1007,"title":1008,"stem":1009},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch23-encapsulation-and-final\u002F1-scope-and-access","Access, final, and Immutability — Exercises","shockwave-curriculum\u002Fexercises\u002Fch23-encapsulation-and-final\u002F23.1-scope-and-access",{"path":1011,"title":1012,"stem":1013},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch24-optional-avoiding-null-pointer-exceptions\u002F24-optional-avoiding-null-pointer-exceptions","Optional: Avoiding Null Pointer Exceptions — Exercises","shockwave-curriculum\u002Fexercises\u002Fch24-optional-avoiding-null-pointer-exceptions\u002F24-optional-avoiding-null-pointer-exceptions",{"path":1015,"title":1016,"stem":1017},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F1-what-is-command-based-programming","What Is Command-Based Programming? — Exercises","shockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F25.1-what-is-command-based-programming",{"path":1019,"title":1020,"stem":1021},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F2-commands-and-command-compositions","Commands & Command Compositions — Exercises","shockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F25.2-commands-and-command-compositions",{"path":1023,"title":1024,"stem":1025},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F3-the-command-scheduler","The Command Scheduler — Exercises","shockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F25.3-the-command-scheduler",{"path":1027,"title":1028,"stem":1029},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F4-state-machines-logic","State Machines: Logic — Exercises","shockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F25.4-state-machines-logic",{"path":1031,"title":1032,"stem":1033},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F5-managing-transitions","Managing Transitions — Exercises","shockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F25.5-managing-transitions",{"path":1035,"title":1036,"stem":1037},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F6-binding-commands-to-triggers","Binding Commands to Triggers — Exercises","shockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F25.6-binding-commands-to-triggers",{"path":1039,"title":1040,"stem":1041},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F7-structuring-a-command-based-robot-project","Structuring a Command-Based Robot Project — Exercises","shockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F25.7-structuring-a-command-based-robot-project",{"path":1043,"title":1044,"stem":1045},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch26-architecture-takeaways\u002F26-architecture-takeaways","Architecture Takeaways — Exercises","shockwave-curriculum\u002Fexercises\u002Fch26-architecture-takeaways\u002F26-architecture-takeaways",{"path":1047,"title":1048,"stem":1049},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch27-program-design-and-abstraction\u002F1-abstraction-and-program-design","Abstraction and Program Design — Exercises","shockwave-curriculum\u002Fexercises\u002Fch27-program-design-and-abstraction\u002F27.1-abstraction-and-program-design",{"path":1051,"title":1052,"stem":1053},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch27-program-design-and-abstraction\u002F2-impact-of-program-design","Impact of Program Design — Exercises","shockwave-curriculum\u002Fexercises\u002Fch27-program-design-and-abstraction\u002F27.2-impact-of-program-design",{"path":1055,"title":1056,"stem":1057},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch28-algorithms-searching-sorting-recursion\u002F1-searching-algorithms","Searching Algorithms — Exercises","shockwave-curriculum\u002Fexercises\u002Fch28-algorithms-searching-sorting-recursion\u002F28.1-searching-algorithms",{"path":1059,"title":1060,"stem":1061},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch28-algorithms-searching-sorting-recursion\u002F2-sorting-algorithms","Sorting Algorithms — Exercises","shockwave-curriculum\u002Fexercises\u002Fch28-algorithms-searching-sorting-recursion\u002F28.2-sorting-algorithms",{"path":1063,"title":1064,"stem":1065},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch28-algorithms-searching-sorting-recursion\u002F3-recursion","Recursion — Exercises","shockwave-curriculum\u002Fexercises\u002Fch28-algorithms-searching-sorting-recursion\u002F28.3-recursion",{"path":1067,"title":1068,"stem":1069},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch28-algorithms-searching-sorting-recursion\u002F4-recursive-searching-and-sorting","Recursive Searching and Sorting — Exercises","shockwave-curriculum\u002Fexercises\u002Fch28-algorithms-searching-sorting-recursion\u002F28.4-recursive-searching-and-sorting",{"id":1071,"title":254,"body":1072,"description":1139,"extension":1829,"meta":1830,"navigation":1236,"path":253,"seo":1833,"stem":255,"__hash__":1834},"lessons\u002Fshockwave-curriculum\u002Flessons\u002Fch21-static-factories\u002F21-static-factories.md",{"type":1073,"value":1074,"toc":1820},"minimark",[1075,1079,1089,1107,1133,1192,1202,1206,1213,1261,1276,1280,1299,1507,1522,1553,1557,1571,1636,1670,1709,1713,1758,1762,1793,1816],[1076,1077,254],"h1",{"id":1078},"static-factories",[1080,1081,1083,1084,1088],"h2",{"id":1082},"why-not-just-new","Why Not Just ",[1085,1086,1087],"code",{},"new","?",[1090,1091,1092,1093,1097,1098,1101,1102,1106],"p",{},"A ",[1094,1095,1096],"strong",{},"static factory method"," is a ",[1085,1099,1100],{},"public static"," method that returns an object, used ",[1103,1104,1105],"em",{},"instead of"," calling a constructor directly. At first glance this looks like extra ceremony for no reason — but it buys a few concrete things a plain constructor can't:",[1108,1109,1110,1121,1127],"ul",{},[1111,1112,1113,1116,1117,1120],"li",{},[1094,1114,1115],{},"A descriptive name."," ",[1085,1118,1119],{},"MyCommands.print(\"Ready\")"," says exactly what you're getting; a constructor overload chosen by argument types alone doesn't communicate intent nearly as clearly.",[1111,1122,1123,1126],{},[1094,1124,1125],{},"The freedom to not construct a new object at all."," A factory method can return a cached, already-existing instance instead of a fresh one — a constructor, by contrast, always creates something new.",[1111,1128,1129,1132],{},[1094,1130,1131],{},"The freedom to return a completely different concrete type",", chosen by logic inside the method — the caller only ever sees the return type (often an interface), never which concrete class was actually picked.",[1134,1135,1140],"pre",{"className":1136,"code":1137,"language":1138,"meta":1139,"style":1139},"language-java shiki shiki-themes github-light github-dark","public class MyCommands\n{\n    public static Command print(String msg)\n    {\n        return Command.noRequirements(coroutine -> System.out.println(msg))\n            .named(\"Print \" + msg);\n    }\n}\n","java","",[1085,1141,1142,1150,1156,1162,1168,1174,1180,1186],{"__ignoreMap":1139},[1143,1144,1147],"span",{"class":1145,"line":1146},"line",1,[1143,1148,1149],{},"public class MyCommands\n",[1143,1151,1153],{"class":1145,"line":1152},2,[1143,1154,1155],{},"{\n",[1143,1157,1159],{"class":1145,"line":1158},3,[1143,1160,1161],{},"    public static Command print(String msg)\n",[1143,1163,1165],{"class":1145,"line":1164},4,[1143,1166,1167],{},"    {\n",[1143,1169,1171],{"class":1145,"line":1170},5,[1143,1172,1173],{},"        return Command.noRequirements(coroutine -> System.out.println(msg))\n",[1143,1175,1177],{"class":1145,"line":1176},6,[1143,1178,1179],{},"            .named(\"Print \" + msg);\n",[1143,1181,1183],{"class":1145,"line":1182},7,[1143,1184,1185],{},"    }\n",[1143,1187,1189],{"class":1145,"line":1188},8,[1143,1190,1191],{},"}\n",[1090,1193,1194,1195,1197,1198,1201],{},"Calling ",[1085,1196,1119],{}," reads clearly as \"give me a command that prints this message\" — the caller never needs to know or care that it's built from ",[1085,1199,1200],{},"Command.noRequirements"," (Lesson 25.2) underneath.",[1080,1203,1205],{"id":1204},"a-concrete-example-returning-a-cached-instance","A Concrete Example: Returning a Cached Instance",[1090,1207,1208,1209,1212],{},"The \"freedom to not construct a new object\" isn't just theoretical — here it is in practice. A factory method can hand back the ",[1103,1210,1211],{},"same"," object every time instead of building a fresh one:",[1134,1214,1216],{"className":1136,"code":1215,"language":1138,"meta":1139,"style":1139},"public class SensorLog\n{\n    private static final SensorLog INSTANCE = new SensorLog();\n\n    public static SensorLog getInstance()\n    {\n        return INSTANCE; \u002F\u002F the same object every call — never a fresh one\n    }\n}\n",[1085,1217,1218,1223,1227,1232,1238,1243,1247,1252,1256],{"__ignoreMap":1139},[1143,1219,1220],{"class":1145,"line":1146},[1143,1221,1222],{},"public class SensorLog\n",[1143,1224,1225],{"class":1145,"line":1152},[1143,1226,1155],{},[1143,1228,1229],{"class":1145,"line":1158},[1143,1230,1231],{},"    private static final SensorLog INSTANCE = new SensorLog();\n",[1143,1233,1234],{"class":1145,"line":1164},[1143,1235,1237],{"emptyLinePlaceholder":1236},true,"\n",[1143,1239,1240],{"class":1145,"line":1170},[1143,1241,1242],{},"    public static SensorLog getInstance()\n",[1143,1244,1245],{"class":1145,"line":1176},[1143,1246,1167],{},[1143,1248,1249],{"class":1145,"line":1182},[1143,1250,1251],{},"        return INSTANCE; \u002F\u002F the same object every call — never a fresh one\n",[1143,1253,1254],{"class":1145,"line":1188},[1143,1255,1185],{},[1143,1257,1259],{"class":1145,"line":1258},9,[1143,1260,1191],{},[1090,1262,1263,1264,1267,1268,1271,1272,1275],{},"Every call to ",[1085,1265,1266],{},"SensorLog.getInstance()"," returns the exact same ",[1085,1269,1270],{},"SensorLog"," object. A constructor could never do this — ",[1085,1273,1274],{},"new SensorLog()"," always builds a new one.",[1080,1277,1279],{"id":1278},"the-real-payoff-choosing-an-implementation-by-condition","The Real Payoff: Choosing an Implementation by Condition",[1090,1281,1282,1283,1286,1287,1290,1291,1294,1295,1298],{},"The pattern's biggest use in FRC code is picking between real and simulated hardware — deciding ",[1103,1284,1285],{},"which"," concrete class to construct, in exactly one place, based on a condition. A factory class like this exists purely to hold ",[1085,1288,1289],{},"static"," members, so it also gets a ",[1085,1292,1293],{},"private"," constructor — nothing outside the class ever needs, or is allowed, to write ",[1085,1296,1297],{},"new DrivetrainFactory()"," (each class below is in its own file):",[1134,1300,1302],{"className":1136,"code":1301,"language":1138,"meta":1139,"style":1139},"public interface Drivetrain\n{\n    void drive(double speed, double turn);\n}\n\npublic class RealDrivetrain implements Drivetrain\n{\n    @Override\n    public void drive(double speed, double turn)\n    {\n        \u002F\u002F control the real motor controllers\n    }\n}\n\npublic class SimDrivetrain implements Drivetrain\n{\n    @Override\n    public void drive(double speed, double turn)\n    {\n        \u002F\u002F simulate motion via WPILib sim\n    }\n}\n\npublic class DrivetrainFactory\n{\n    private DrivetrainFactory() {} \u002F\u002F never instantiated — only static members\n\n    public static Drivetrain createDrivetrain()\n    {\n        if (RobotBase.isReal())\n        {\n            return new RealDrivetrain();\n        }\n        else\n        {\n            return new SimDrivetrain();\n        }\n    }\n}\n",[1085,1303,1304,1309,1313,1318,1322,1326,1331,1335,1340,1345,1350,1356,1361,1366,1371,1377,1382,1387,1392,1397,1403,1408,1413,1418,1424,1429,1435,1440,1446,1451,1457,1463,1469,1475,1481,1486,1492,1497,1502],{"__ignoreMap":1139},[1143,1305,1306],{"class":1145,"line":1146},[1143,1307,1308],{},"public interface Drivetrain\n",[1143,1310,1311],{"class":1145,"line":1152},[1143,1312,1155],{},[1143,1314,1315],{"class":1145,"line":1158},[1143,1316,1317],{},"    void drive(double speed, double turn);\n",[1143,1319,1320],{"class":1145,"line":1164},[1143,1321,1191],{},[1143,1323,1324],{"class":1145,"line":1170},[1143,1325,1237],{"emptyLinePlaceholder":1236},[1143,1327,1328],{"class":1145,"line":1176},[1143,1329,1330],{},"public class RealDrivetrain implements Drivetrain\n",[1143,1332,1333],{"class":1145,"line":1182},[1143,1334,1155],{},[1143,1336,1337],{"class":1145,"line":1188},[1143,1338,1339],{},"    @Override\n",[1143,1341,1342],{"class":1145,"line":1258},[1143,1343,1344],{},"    public void drive(double speed, double turn)\n",[1143,1346,1348],{"class":1145,"line":1347},10,[1143,1349,1167],{},[1143,1351,1353],{"class":1145,"line":1352},11,[1143,1354,1355],{},"        \u002F\u002F control the real motor controllers\n",[1143,1357,1359],{"class":1145,"line":1358},12,[1143,1360,1185],{},[1143,1362,1364],{"class":1145,"line":1363},13,[1143,1365,1191],{},[1143,1367,1369],{"class":1145,"line":1368},14,[1143,1370,1237],{"emptyLinePlaceholder":1236},[1143,1372,1374],{"class":1145,"line":1373},15,[1143,1375,1376],{},"public class SimDrivetrain implements Drivetrain\n",[1143,1378,1380],{"class":1145,"line":1379},16,[1143,1381,1155],{},[1143,1383,1385],{"class":1145,"line":1384},17,[1143,1386,1339],{},[1143,1388,1390],{"class":1145,"line":1389},18,[1143,1391,1344],{},[1143,1393,1395],{"class":1145,"line":1394},19,[1143,1396,1167],{},[1143,1398,1400],{"class":1145,"line":1399},20,[1143,1401,1402],{},"        \u002F\u002F simulate motion via WPILib sim\n",[1143,1404,1406],{"class":1145,"line":1405},21,[1143,1407,1185],{},[1143,1409,1411],{"class":1145,"line":1410},22,[1143,1412,1191],{},[1143,1414,1416],{"class":1145,"line":1415},23,[1143,1417,1237],{"emptyLinePlaceholder":1236},[1143,1419,1421],{"class":1145,"line":1420},24,[1143,1422,1423],{},"public class DrivetrainFactory\n",[1143,1425,1427],{"class":1145,"line":1426},25,[1143,1428,1155],{},[1143,1430,1432],{"class":1145,"line":1431},26,[1143,1433,1434],{},"    private DrivetrainFactory() {} \u002F\u002F never instantiated — only static members\n",[1143,1436,1438],{"class":1145,"line":1437},27,[1143,1439,1237],{"emptyLinePlaceholder":1236},[1143,1441,1443],{"class":1145,"line":1442},28,[1143,1444,1445],{},"    public static Drivetrain createDrivetrain()\n",[1143,1447,1449],{"class":1145,"line":1448},29,[1143,1450,1167],{},[1143,1452,1454],{"class":1145,"line":1453},30,[1143,1455,1456],{},"        if (RobotBase.isReal())\n",[1143,1458,1460],{"class":1145,"line":1459},31,[1143,1461,1462],{},"        {\n",[1143,1464,1466],{"class":1145,"line":1465},32,[1143,1467,1468],{},"            return new RealDrivetrain();\n",[1143,1470,1472],{"class":1145,"line":1471},33,[1143,1473,1474],{},"        }\n",[1143,1476,1478],{"class":1145,"line":1477},34,[1143,1479,1480],{},"        else\n",[1143,1482,1484],{"class":1145,"line":1483},35,[1143,1485,1462],{},[1143,1487,1489],{"class":1145,"line":1488},36,[1143,1490,1491],{},"            return new SimDrivetrain();\n",[1143,1493,1495],{"class":1145,"line":1494},37,[1143,1496,1474],{},[1143,1498,1500],{"class":1145,"line":1499},38,[1143,1501,1185],{},[1143,1503,1505],{"class":1145,"line":1504},39,[1143,1506,1191],{},[1134,1508,1510],{"className":1136,"code":1509,"language":1138,"meta":1139,"style":1139},"\u002F\u002F caller never picks the concrete class itself\nDrivetrain drivetrain = DrivetrainFactory.createDrivetrain();\n",[1085,1511,1512,1517],{"__ignoreMap":1139},[1143,1513,1514],{"class":1145,"line":1146},[1143,1515,1516],{},"\u002F\u002F caller never picks the concrete class itself\n",[1143,1518,1519],{"class":1145,"line":1152},[1143,1520,1521],{},"Drivetrain drivetrain = DrivetrainFactory.createDrivetrain();\n",[1090,1523,1524,1525,1528,1529,1532,1533,1536,1537,1540,1541,1544,1545,1548,1549,1552],{},"This is a genuine alternative to the constructor-injection style from the IO-Layer Pattern (Ch.20) — ",[1094,1526,1527],{},"constructor injection"," means the caller decides which implementation to use and passes (\"injects\") it in through a constructor parameter, the way Ch.20's ",[1085,1530,1531],{},"Robot"," constructor builds ",[1085,1534,1535],{},"new Intake(new IntakeIOReal())"," itself. A factory flips that: instead of the caller deciding, the factory itself makes the real-vs-sim decision, centralizing that one ",[1085,1538,1539],{},"if (RobotBase.isReal())"," check inside ",[1085,1542,1543],{},"createDrivetrain()"," rather than repeating it at every construction site. WPILib's own API uses this pattern too — ",[1085,1546,1547],{},"Rotation2d.fromDegrees(90)"," (Lesson 4.5) is a real static factory, more descriptive than calling ",[1085,1550,1551],{},"Rotation2d","'s constructor with radians directly.",[1080,1554,1556],{"id":1555},"factories-for-more-than-hardware","Factories for More Than Hardware",[1090,1558,1559,1560,1116,1563,1566,1567,1570],{},"The same idea works for building the right object out of a whole family of choices — not just two (real\u002Fsim), but any number, selected by some other input. This is a ",[1085,1561,1562],{},"switch",[1094,1564,1565],{},"expression"," (Lesson 5.12) over a ",[1085,1568,1569],{},"String",":",[1134,1572,1574],{"className":1136,"code":1573,"language":1138,"meta":1139,"style":1139},"public class AutoFactory\n{\n    public static Command createAuto(String mode)\n    {\n        return switch (mode)\n        {\n            case \"Taxi\" -> MyCommands.driveForward(3.0);\n            case \"2 Ball\" -> MyCommands.twoBallAuto();\n            case \"Nothing\" -> Command.waitFor(Seconds.of(0.1)).named(\"Do Nothing\");\n            case null, default -> MyCommands.print(\"Unknown Auto Mode\");\n        };\n    }\n}\n",[1085,1575,1576,1581,1585,1590,1594,1599,1603,1608,1613,1618,1623,1628,1632],{"__ignoreMap":1139},[1143,1577,1578],{"class":1145,"line":1146},[1143,1579,1580],{},"public class AutoFactory\n",[1143,1582,1583],{"class":1145,"line":1152},[1143,1584,1155],{},[1143,1586,1587],{"class":1145,"line":1158},[1143,1588,1589],{},"    public static Command createAuto(String mode)\n",[1143,1591,1592],{"class":1145,"line":1164},[1143,1593,1167],{},[1143,1595,1596],{"class":1145,"line":1170},[1143,1597,1598],{},"        return switch (mode)\n",[1143,1600,1601],{"class":1145,"line":1176},[1143,1602,1462],{},[1143,1604,1605],{"class":1145,"line":1182},[1143,1606,1607],{},"            case \"Taxi\" -> MyCommands.driveForward(3.0);\n",[1143,1609,1610],{"class":1145,"line":1188},[1143,1611,1612],{},"            case \"2 Ball\" -> MyCommands.twoBallAuto();\n",[1143,1614,1615],{"class":1145,"line":1258},[1143,1616,1617],{},"            case \"Nothing\" -> Command.waitFor(Seconds.of(0.1)).named(\"Do Nothing\");\n",[1143,1619,1620],{"class":1145,"line":1347},[1143,1621,1622],{},"            case null, default -> MyCommands.print(\"Unknown Auto Mode\");\n",[1143,1624,1625],{"class":1145,"line":1352},[1143,1626,1627],{},"        };\n",[1143,1629,1630],{"class":1145,"line":1358},[1143,1631,1185],{},[1143,1633,1634],{"class":1145,"line":1363},[1143,1635,1191],{},[1134,1637,1639],{"className":1136,"code":1638,"language":1138,"meta":1139,"style":1139},"\u002F\u002F org.wpilib.tunable — the 2027 driver-station chooser\nSelectable\u003CString> chooser = new Selectable\u003C>();\nchooser.addDefault(\"Taxi\", \"Taxi\");\n\n\u002F\u002F built from whatever the driver station selected\nCommand auto = AutoFactory.createAuto(chooser.getSelected());\n",[1085,1640,1641,1646,1651,1656,1660,1665],{"__ignoreMap":1139},[1143,1642,1643],{"class":1145,"line":1146},[1143,1644,1645],{},"\u002F\u002F org.wpilib.tunable — the 2027 driver-station chooser\n",[1143,1647,1648],{"class":1145,"line":1152},[1143,1649,1650],{},"Selectable\u003CString> chooser = new Selectable\u003C>();\n",[1143,1652,1653],{"class":1145,"line":1158},[1143,1654,1655],{},"chooser.addDefault(\"Taxi\", \"Taxi\");\n",[1143,1657,1658],{"class":1145,"line":1164},[1143,1659,1237],{"emptyLinePlaceholder":1236},[1143,1661,1662],{"class":1145,"line":1170},[1143,1663,1664],{},"\u002F\u002F built from whatever the driver station selected\n",[1143,1666,1667],{"class":1145,"line":1176},[1143,1668,1669],{},"Command auto = AutoFactory.createAuto(chooser.getSelected());\n",[1090,1671,1672,1675,1676,1679,1680,1683,1684,1687,1688,1691,1692,1694,1695,1697,1698,1701,1702,1705,1706,1708],{},[1085,1673,1674],{},"chooser.getSelected()"," can return ",[1085,1677,1678],{},"null"," if nothing was ever selected ",[1103,1681,1682],{},"and"," no default was set with ",[1085,1685,1686],{},"addDefault(...)"," — a plain ",[1085,1689,1690],{},"default"," case doesn't catch ",[1085,1693,1678],{},", and switching on a ",[1085,1696,1678],{}," String otherwise throws a ",[1085,1699,1700],{},"NullPointerException",". ",[1085,1703,1704],{},"case null, default ->"," (Java 21+ pattern matching for switch) explicitly routes a ",[1085,1707,1678],{}," mode to the same fallback as any other unrecognized one.",[1080,1710,1712],{"id":1711},"common-pitfalls","Common Pitfalls",[1108,1714,1715,1728,1745],{},[1111,1716,1717,1116,1720,1723,1724,1727],{},[1094,1718,1719],{},"Returning a concrete class instead of an interface.",[1085,1721,1722],{},"public static RealDrivetrain createDrivetrain()"," locks callers into one specific implementation — return the interface type (",[1085,1725,1726],{},"Drivetrain",") so the real choice stays hidden inside the factory.",[1111,1729,1730,1737,1738,1741,1742,1744],{},[1094,1731,1732,1733,1736],{},"Duplicating the same real-vs-sim ",[1085,1734,1735],{},"if"," check in multiple places."," The whole point of a factory is centralizing that decision in one method — scattering ",[1085,1739,1740],{},"RobotBase.isReal()"," checks throughout the codebase (instead of injecting once, as Ch.20's ",[1085,1743,1531],{}," constructor does, or factoring it into one method here) defeats the purpose.",[1111,1746,1747,1750,1751,1753,1754,1757],{},[1094,1748,1749],{},"Confusing a factory with a constructor."," A factory method is just a regular ",[1085,1752,1289],{}," method — it can return a cached instance or pick any subtype, neither of which a constructor is free to do (a constructor always returns a new instance of its own exact class). A factory method ",[1103,1755,1756],{},"can"," validate its arguments, but so can a constructor (Lesson 12) — that part isn't a difference between them.",[1080,1759,1761],{"id":1760},"key-takeaways","Key Takeaways",[1108,1763,1764,1770,1773,1785],{},[1111,1765,1766,1767,1769],{},"A static factory method returns an object in place of a direct constructor call, with a descriptive name, the option to return a cached instance (",[1085,1768,1266],{},"), and the freedom to choose the actual concrete type internally.",[1111,1771,1772],{},"Its most common FRC use: centralizing real-vs-simulated (or comp-bot-vs-practice-bot) selection logic in one place, so callers only ever depend on an interface. This is an alternative to constructor injection (Ch.20) — the factory decides, instead of the caller.",[1111,1774,1775,1776,1778,1779,1781,1782,1784],{},"Factories generalize beyond hardware — anything selected by a condition (an autonomous mode, a config option) is a natural fit; a ",[1085,1777,1562],{}," expression choosing between commands needs ",[1085,1780,1704],{}," if the input could be ",[1085,1783,1678],{},".",[1111,1786,1787,1788,1790,1791,1784],{},"Always return the interface type from a factory method, not a specific concrete class, so the actual implementation choice stays hidden from callers. A factory-only class gets a ",[1085,1789,1293],{}," constructor, since nothing should ever build one with ",[1085,1792,1087],{},[1090,1794,1795,1796,1799,1800,1803,1804,1807,1808,1811,1812,1815],{},"Derived from ",[1085,1797,1798],{},"other-reference-repo",": ",[1085,1801,1802],{},"team-5817-training\u002Fdesign-patterns\u002Ffactory.md"," (T5817 30.2); updated for Commands v3 from allwpilib ",[1085,1805,1806],{},"main"," (",[1085,1809,1810],{},"commandsv3\u002F…\u002Fcommand3\u002FCommand.java",")\n",[1094,1813,1814],{},"Deck context:"," mechacoder-test\u002Fsrc\u002Flessons\u002Fjava-2.js, slide 7 (\"Static Factories\")",[1817,1818,1819],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":1139,"searchDepth":1152,"depth":1152,"links":1821},[1822,1824,1825,1826,1827,1828],{"id":1082,"depth":1152,"text":1823},"Why Not Just new?",{"id":1204,"depth":1152,"text":1205},{"id":1278,"depth":1152,"text":1279},{"id":1555,"depth":1152,"text":1556},{"id":1711,"depth":1152,"text":1712},{"id":1760,"depth":1152,"text":1761},"md",{"outlineRef":1831,"status":1832},"21 — Static Factories (T5817 30.2)","new — authored lesson (fuller depth than the teaser slide)",{"title":254,"description":1139},"8mCbvZhJSmRBw2UPCd6j6C4fQTQvE3JlvkHKsySi7WE",{"id":1836,"title":687,"body":1837,"description":1139,"extension":1829,"meta":2655,"navigation":1236,"path":686,"seo":2658,"stem":688,"__hash__":2659},"examples\u002Fshockwave-curriculum\u002Fexamples\u002Fch21-static-factories\u002F21-static-factories.md",{"type":1073,"value":1838,"toc":2642},[1839,1842,1846,1849,1853,1877,1881,1904,1911,1915,2024,2030,2034,2118,2121,2163,2177,2183,2238,2261,2265,2278,2544,2548,2556,2580,2584,2587,2596,2610,2614,2640],[1076,1840,687],{"id":1841},"static-factories-worked-example",[1080,1843,1845],{"id":1844},"problem","Problem",[1090,1847,1848],{},"The robot's LED strip should show the team's alliance color: solid red on the red alliance, solid blue on the blue alliance, and blinking yellow as a warning when the alliance isn't known yet. Several parts of the robot code need \"the right pattern for this alliance.\" Write one static factory method that makes that choice, so no caller ever has to pick the concrete pattern class itself.",[1080,1850,1852],{"id":1851},"step-1-plan-it-first","Step 1: Plan It First",[1854,1855,1856,1863,1866,1871],"ol",{},[1111,1857,1858,1859,1862],{},"Define an interface, ",[1085,1860,1861],{},"LedPattern",", as the one type every caller works with.",[1111,1864,1865],{},"Write the concrete pattern classes that implement it.",[1111,1867,1868,1869,1784],{},"Write a static factory method that takes the alliance name and returns the right ",[1085,1870,1861],{},[1111,1872,1873,1874,1876],{},"Call the factory from ",[1085,1875,1806],{}," for a known alliance and an unknown one.",[1080,1878,1880],{"id":1879},"step-2-the-interface-every-caller-uses","Step 2: The Interface Every Caller Uses",[1134,1882,1884],{"className":1136,"code":1883,"language":1138,"meta":1139,"style":1139},"interface LedPattern\n{\n    String describe();\n}\n",[1085,1885,1886,1891,1895,1900],{"__ignoreMap":1139},[1143,1887,1888],{"class":1145,"line":1146},[1143,1889,1890],{},"interface LedPattern\n",[1143,1892,1893],{"class":1145,"line":1152},[1143,1894,1155],{},[1143,1896,1897],{"class":1145,"line":1158},[1143,1898,1899],{},"    String describe();\n",[1143,1901,1902],{"class":1145,"line":1164},[1143,1903,1191],{},[1090,1905,1906,1907,1910],{},"A real LED pattern would drive the strip. ",[1085,1908,1909],{},"describe()"," stands in for that here, so the program can print which pattern it got.",[1080,1912,1914],{"id":1913},"step-3-the-concrete-patterns","Step 3: The Concrete Patterns",[1134,1916,1918],{"className":1136,"code":1917,"language":1138,"meta":1139,"style":1139},"class SolidColor implements LedPattern\n{\n    private String color;\n\n    public SolidColor(String color)\n    {\n        this.color = color;\n    }\n\n    @Override\n    public String describe()\n    {\n        return \"solid \" + color;\n    }\n}\n\nclass BlinkingYellow implements LedPattern\n{\n    @Override\n    public String describe()\n    {\n        return \"blinking yellow\";\n    }\n}\n",[1085,1919,1920,1925,1929,1934,1938,1943,1947,1952,1956,1960,1964,1969,1973,1978,1982,1986,1990,1995,1999,2003,2007,2011,2016,2020],{"__ignoreMap":1139},[1143,1921,1922],{"class":1145,"line":1146},[1143,1923,1924],{},"class SolidColor implements LedPattern\n",[1143,1926,1927],{"class":1145,"line":1152},[1143,1928,1155],{},[1143,1930,1931],{"class":1145,"line":1158},[1143,1932,1933],{},"    private String color;\n",[1143,1935,1936],{"class":1145,"line":1164},[1143,1937,1237],{"emptyLinePlaceholder":1236},[1143,1939,1940],{"class":1145,"line":1170},[1143,1941,1942],{},"    public SolidColor(String color)\n",[1143,1944,1945],{"class":1145,"line":1176},[1143,1946,1167],{},[1143,1948,1949],{"class":1145,"line":1182},[1143,1950,1951],{},"        this.color = color;\n",[1143,1953,1954],{"class":1145,"line":1188},[1143,1955,1185],{},[1143,1957,1958],{"class":1145,"line":1258},[1143,1959,1237],{"emptyLinePlaceholder":1236},[1143,1961,1962],{"class":1145,"line":1347},[1143,1963,1339],{},[1143,1965,1966],{"class":1145,"line":1352},[1143,1967,1968],{},"    public String describe()\n",[1143,1970,1971],{"class":1145,"line":1358},[1143,1972,1167],{},[1143,1974,1975],{"class":1145,"line":1363},[1143,1976,1977],{},"        return \"solid \" + color;\n",[1143,1979,1980],{"class":1145,"line":1368},[1143,1981,1185],{},[1143,1983,1984],{"class":1145,"line":1373},[1143,1985,1191],{},[1143,1987,1988],{"class":1145,"line":1379},[1143,1989,1237],{"emptyLinePlaceholder":1236},[1143,1991,1992],{"class":1145,"line":1384},[1143,1993,1994],{},"class BlinkingYellow implements LedPattern\n",[1143,1996,1997],{"class":1145,"line":1389},[1143,1998,1155],{},[1143,2000,2001],{"class":1145,"line":1394},[1143,2002,1339],{},[1143,2004,2005],{"class":1145,"line":1399},[1143,2006,1968],{},[1143,2008,2009],{"class":1145,"line":1405},[1143,2010,1167],{},[1143,2012,2013],{"class":1145,"line":1410},[1143,2014,2015],{},"        return \"blinking yellow\";\n",[1143,2017,2018],{"class":1145,"line":1415},[1143,2019,1185],{},[1143,2021,2022],{"class":1145,"line":1420},[1143,2023,1191],{},[1090,2025,2026,2027,2029],{},"There are two different concrete classes, and both honor the same ",[1085,2028,1861],{}," contract.",[1080,2031,2033],{"id":2032},"step-4-the-factory-method","Step 4: The Factory Method",[1134,2035,2037],{"className":1136,"code":2036,"language":1138,"meta":1139,"style":1139},"class LedPatterns\n{\n    public static LedPattern forAlliance(String alliance)\n    {\n        if (alliance.equals(\"Red\"))\n        {\n            return new SolidColor(\"red\");\n        }\n        else if (alliance.equals(\"Blue\"))\n        {\n            return new SolidColor(\"blue\");\n        }\n        else\n        {\n            return new BlinkingYellow(); \u002F\u002F alliance not known yet: warn the drive team\n        }\n    }\n}\n",[1085,2038,2039,2044,2048,2053,2057,2062,2066,2071,2075,2080,2084,2089,2093,2097,2101,2106,2110,2114],{"__ignoreMap":1139},[1143,2040,2041],{"class":1145,"line":1146},[1143,2042,2043],{},"class LedPatterns\n",[1143,2045,2046],{"class":1145,"line":1152},[1143,2047,1155],{},[1143,2049,2050],{"class":1145,"line":1158},[1143,2051,2052],{},"    public static LedPattern forAlliance(String alliance)\n",[1143,2054,2055],{"class":1145,"line":1164},[1143,2056,1167],{},[1143,2058,2059],{"class":1145,"line":1170},[1143,2060,2061],{},"        if (alliance.equals(\"Red\"))\n",[1143,2063,2064],{"class":1145,"line":1176},[1143,2065,1462],{},[1143,2067,2068],{"class":1145,"line":1182},[1143,2069,2070],{},"            return new SolidColor(\"red\");\n",[1143,2072,2073],{"class":1145,"line":1188},[1143,2074,1474],{},[1143,2076,2077],{"class":1145,"line":1258},[1143,2078,2079],{},"        else if (alliance.equals(\"Blue\"))\n",[1143,2081,2082],{"class":1145,"line":1347},[1143,2083,1462],{},[1143,2085,2086],{"class":1145,"line":1352},[1143,2087,2088],{},"            return new SolidColor(\"blue\");\n",[1143,2090,2091],{"class":1145,"line":1358},[1143,2092,1474],{},[1143,2094,2095],{"class":1145,"line":1363},[1143,2096,1480],{},[1143,2098,2099],{"class":1145,"line":1368},[1143,2100,1462],{},[1143,2102,2103],{"class":1145,"line":1373},[1143,2104,2105],{},"            return new BlinkingYellow(); \u002F\u002F alliance not known yet: warn the drive team\n",[1143,2107,2108],{"class":1145,"line":1379},[1143,2109,1474],{},[1143,2111,2112],{"class":1145,"line":1384},[1143,2113,1185],{},[1143,2115,2116],{"class":1145,"line":1389},[1143,2117,1191],{},[1090,2119,2120],{},"Three things make this a proper static factory, all straight from the lesson:",[1108,2122,2123,2139,2152],{},[1111,2124,2125,2130,2131,2134,2135,2138],{},[1094,2126,2127,2128,1784],{},"It's ",[1085,2129,1100],{}," Callers use the class name, ",[1085,2132,2133],{},"LedPatterns.forAlliance(...)",". They don't need an ",[1085,2136,2137],{},"LedPatterns"," object first.",[1111,2140,2141,1116,2144,2147,2148,2151],{},[1094,2142,2143],{},"It has a descriptive name.",[1085,2145,2146],{},"LedPatterns.forAlliance(\"Red\")"," says what you're getting. Compare that with ",[1085,2149,2150],{},"new SolidColor(\"red\")",", which makes the caller already know which class and which color string to use.",[1111,2153,2154,2159,2160,2162],{},[1094,2155,2156,2157,1784],{},"It returns the interface type, ",[1085,2158,1861],{}," Inside, it picks between two completely different concrete classes. The caller only ever sees ",[1085,2161,1861],{},", so the choice stays hidden in this one method.",[1090,2164,2165,2166,2169,2170,2173,2174,2176],{},"The alliance names are compared with ",[1085,2167,2168],{},".equals()"," (Ch.6), not ",[1085,2171,2172],{},"==",", since they're ",[1085,2175,1569],{},"s.",[1080,2178,2180,2181],{"id":2179},"step-5-call-it-from-main","Step 5: Call It From ",[1085,2182,1806],{},[1134,2184,2186],{"className":1136,"code":2185,"language":1138,"meta":1139,"style":1139},"public class LedDemo\n{\n    public static void main(String[] args)\n    {\n        LedPattern blueLights = LedPatterns.forAlliance(\"Blue\");\n        LedPattern unknownLights = LedPatterns.forAlliance(\"\");\n\n        System.out.println(\"Blue alliance: \" + blueLights.describe());\n        System.out.println(\"No alliance yet: \" + unknownLights.describe());\n    }\n}\n",[1085,2187,2188,2193,2197,2202,2206,2211,2216,2220,2225,2230,2234],{"__ignoreMap":1139},[1143,2189,2190],{"class":1145,"line":1146},[1143,2191,2192],{},"public class LedDemo\n",[1143,2194,2195],{"class":1145,"line":1152},[1143,2196,1155],{},[1143,2198,2199],{"class":1145,"line":1158},[1143,2200,2201],{},"    public static void main(String[] args)\n",[1143,2203,2204],{"class":1145,"line":1164},[1143,2205,1167],{},[1143,2207,2208],{"class":1145,"line":1170},[1143,2209,2210],{},"        LedPattern blueLights = LedPatterns.forAlliance(\"Blue\");\n",[1143,2212,2213],{"class":1145,"line":1176},[1143,2214,2215],{},"        LedPattern unknownLights = LedPatterns.forAlliance(\"\");\n",[1143,2217,2218],{"class":1145,"line":1182},[1143,2219,1237],{"emptyLinePlaceholder":1236},[1143,2221,2222],{"class":1145,"line":1188},[1143,2223,2224],{},"        System.out.println(\"Blue alliance: \" + blueLights.describe());\n",[1143,2226,2227],{"class":1145,"line":1258},[1143,2228,2229],{},"        System.out.println(\"No alliance yet: \" + unknownLights.describe());\n",[1143,2231,2232],{"class":1145,"line":1347},[1143,2233,1185],{},[1143,2235,2236],{"class":1145,"line":1352},[1143,2237,1191],{},[1090,2239,2240,2241,2243,2244,2246,2247,2250,2251,2254,2255,2257,2258,2260],{},"Neither line in ",[1085,2242,1806],{}," says ",[1085,2245,1087],{},", and neither mentions ",[1085,2248,2249],{},"SolidColor"," or ",[1085,2252,2253],{},"BlinkingYellow",". Both variables are declared as ",[1085,2256,1861],{},", and each ",[1085,2259,1909],{}," call dispatches to whichever concrete class the factory picked.",[1080,2262,2264],{"id":2263},"step-6-the-whole-program","Step 6: The Whole Program",[1090,2266,2267,2270,2271,2273,2274,2277],{},[1085,2268,2269],{},"LedDemo",", the public class with ",[1085,2272,1806],{},", comes first in the file (on Java 17, ",[1085,2275,2276],{},"java File.java"," source-launch only runs the first class in the file; Java 25 is more lenient, but leading with the public class works on both):",[1134,2279,2281],{"className":1136,"code":2280,"language":1138,"meta":1139,"style":1139},"public class LedDemo\n{\n    public static void main(String[] args)\n    {\n        LedPattern blueLights = LedPatterns.forAlliance(\"Blue\");\n        LedPattern unknownLights = LedPatterns.forAlliance(\"\");\n\n        System.out.println(\"Blue alliance: \" + blueLights.describe());\n        System.out.println(\"No alliance yet: \" + unknownLights.describe());\n    }\n}\n\ninterface LedPattern\n{\n    String describe();\n}\n\nclass SolidColor implements LedPattern\n{\n    private String color;\n\n    public SolidColor(String color)\n    {\n        this.color = color;\n    }\n\n    @Override\n    public String describe()\n    {\n        return \"solid \" + color;\n    }\n}\n\nclass BlinkingYellow implements LedPattern\n{\n    @Override\n    public String describe()\n    {\n        return \"blinking yellow\";\n    }\n}\n\nclass LedPatterns\n{\n    public static LedPattern forAlliance(String alliance)\n    {\n        if (alliance.equals(\"Red\"))\n        {\n            return new SolidColor(\"red\");\n        }\n        else if (alliance.equals(\"Blue\"))\n        {\n            return new SolidColor(\"blue\");\n        }\n        else\n        {\n            return new BlinkingYellow(); \u002F\u002F alliance not known yet: warn the drive team\n        }\n    }\n}\n",[1085,2282,2283,2287,2291,2295,2299,2303,2307,2311,2315,2319,2323,2327,2331,2335,2339,2343,2347,2351,2355,2359,2363,2367,2371,2375,2379,2383,2387,2391,2395,2399,2403,2407,2411,2415,2419,2423,2427,2431,2435,2439,2444,2449,2454,2459,2464,2469,2474,2479,2484,2489,2494,2499,2504,2509,2514,2519,2524,2529,2534,2539],{"__ignoreMap":1139},[1143,2284,2285],{"class":1145,"line":1146},[1143,2286,2192],{},[1143,2288,2289],{"class":1145,"line":1152},[1143,2290,1155],{},[1143,2292,2293],{"class":1145,"line":1158},[1143,2294,2201],{},[1143,2296,2297],{"class":1145,"line":1164},[1143,2298,1167],{},[1143,2300,2301],{"class":1145,"line":1170},[1143,2302,2210],{},[1143,2304,2305],{"class":1145,"line":1176},[1143,2306,2215],{},[1143,2308,2309],{"class":1145,"line":1182},[1143,2310,1237],{"emptyLinePlaceholder":1236},[1143,2312,2313],{"class":1145,"line":1188},[1143,2314,2224],{},[1143,2316,2317],{"class":1145,"line":1258},[1143,2318,2229],{},[1143,2320,2321],{"class":1145,"line":1347},[1143,2322,1185],{},[1143,2324,2325],{"class":1145,"line":1352},[1143,2326,1191],{},[1143,2328,2329],{"class":1145,"line":1358},[1143,2330,1237],{"emptyLinePlaceholder":1236},[1143,2332,2333],{"class":1145,"line":1363},[1143,2334,1890],{},[1143,2336,2337],{"class":1145,"line":1368},[1143,2338,1155],{},[1143,2340,2341],{"class":1145,"line":1373},[1143,2342,1899],{},[1143,2344,2345],{"class":1145,"line":1379},[1143,2346,1191],{},[1143,2348,2349],{"class":1145,"line":1384},[1143,2350,1237],{"emptyLinePlaceholder":1236},[1143,2352,2353],{"class":1145,"line":1389},[1143,2354,1924],{},[1143,2356,2357],{"class":1145,"line":1394},[1143,2358,1155],{},[1143,2360,2361],{"class":1145,"line":1399},[1143,2362,1933],{},[1143,2364,2365],{"class":1145,"line":1405},[1143,2366,1237],{"emptyLinePlaceholder":1236},[1143,2368,2369],{"class":1145,"line":1410},[1143,2370,1942],{},[1143,2372,2373],{"class":1145,"line":1415},[1143,2374,1167],{},[1143,2376,2377],{"class":1145,"line":1420},[1143,2378,1951],{},[1143,2380,2381],{"class":1145,"line":1426},[1143,2382,1185],{},[1143,2384,2385],{"class":1145,"line":1431},[1143,2386,1237],{"emptyLinePlaceholder":1236},[1143,2388,2389],{"class":1145,"line":1437},[1143,2390,1339],{},[1143,2392,2393],{"class":1145,"line":1442},[1143,2394,1968],{},[1143,2396,2397],{"class":1145,"line":1448},[1143,2398,1167],{},[1143,2400,2401],{"class":1145,"line":1453},[1143,2402,1977],{},[1143,2404,2405],{"class":1145,"line":1459},[1143,2406,1185],{},[1143,2408,2409],{"class":1145,"line":1465},[1143,2410,1191],{},[1143,2412,2413],{"class":1145,"line":1471},[1143,2414,1237],{"emptyLinePlaceholder":1236},[1143,2416,2417],{"class":1145,"line":1477},[1143,2418,1994],{},[1143,2420,2421],{"class":1145,"line":1483},[1143,2422,1155],{},[1143,2424,2425],{"class":1145,"line":1488},[1143,2426,1339],{},[1143,2428,2429],{"class":1145,"line":1494},[1143,2430,1968],{},[1143,2432,2433],{"class":1145,"line":1499},[1143,2434,1167],{},[1143,2436,2437],{"class":1145,"line":1504},[1143,2438,2015],{},[1143,2440,2442],{"class":1145,"line":2441},40,[1143,2443,1185],{},[1143,2445,2447],{"class":1145,"line":2446},41,[1143,2448,1191],{},[1143,2450,2452],{"class":1145,"line":2451},42,[1143,2453,1237],{"emptyLinePlaceholder":1236},[1143,2455,2457],{"class":1145,"line":2456},43,[1143,2458,2043],{},[1143,2460,2462],{"class":1145,"line":2461},44,[1143,2463,1155],{},[1143,2465,2467],{"class":1145,"line":2466},45,[1143,2468,2052],{},[1143,2470,2472],{"class":1145,"line":2471},46,[1143,2473,1167],{},[1143,2475,2477],{"class":1145,"line":2476},47,[1143,2478,2061],{},[1143,2480,2482],{"class":1145,"line":2481},48,[1143,2483,1462],{},[1143,2485,2487],{"class":1145,"line":2486},49,[1143,2488,2070],{},[1143,2490,2492],{"class":1145,"line":2491},50,[1143,2493,1474],{},[1143,2495,2497],{"class":1145,"line":2496},51,[1143,2498,2079],{},[1143,2500,2502],{"class":1145,"line":2501},52,[1143,2503,1462],{},[1143,2505,2507],{"class":1145,"line":2506},53,[1143,2508,2088],{},[1143,2510,2512],{"class":1145,"line":2511},54,[1143,2513,1474],{},[1143,2515,2517],{"class":1145,"line":2516},55,[1143,2518,1480],{},[1143,2520,2522],{"class":1145,"line":2521},56,[1143,2523,1462],{},[1143,2525,2527],{"class":1145,"line":2526},57,[1143,2528,2105],{},[1143,2530,2532],{"class":1145,"line":2531},58,[1143,2533,1474],{},[1143,2535,2537],{"class":1145,"line":2536},59,[1143,2538,1185],{},[1143,2540,2542],{"class":1145,"line":2541},60,[1143,2543,1191],{},[1080,2545,2547],{"id":2546},"what-it-prints","What It Prints",[1134,2549,2554],{"className":2550,"code":2552,"language":2553},[2551],"language-text","Blue alliance: solid blue\nNo alliance yet: blinking yellow\n","text",[1085,2555,2552],{"__ignoreMap":1139},[1090,2557,2558,2561,2562,2565,2566,2569,2570,2573,2574,2577,2578,1784],{},[1085,2559,2560],{},"\"Blue\""," matches the ",[1085,2563,2564],{},"else if",", so the factory builds a ",[1085,2567,2568],{},"SolidColor(\"blue\")",". The empty string ",[1085,2571,2572],{},"\"\""," matches neither name and falls through to the ",[1085,2575,2576],{},"else",", so it builds a ",[1085,2579,2253],{},[1080,2581,2583],{"id":2582},"what-returning-the-concrete-type-would-look-like","What Returning the Concrete Type Would Look Like",[1090,2585,2586],{},"The lesson warns against a factory whose return type is a specific class instead of the interface. Say the signature were changed to:",[1134,2588,2590],{"className":1136,"code":2589,"language":1138,"meta":1139,"style":1139},"public static SolidColor forAlliance(String alliance)\n",[1085,2591,2592],{"__ignoreMap":1139},[1143,2593,2594],{"class":1145,"line":1146},[1143,2595,2589],{},[1090,2597,2598,2599,2602,2603,2606,2607,2609],{},"This version doesn't compile at all. The compiler rejects ",[1085,2600,2601],{},"return new BlinkingYellow();"," with ",[1085,2604,2605],{},"incompatible types: BlinkingYellow cannot be converted to SolidColor",". A factory locked to one concrete return type loses the freedom to choose between implementations, which is the main reason to write one. Declaring the return type as ",[1085,2608,1861],{}," is what keeps that choice open.",[1080,2611,2613],{"id":2612},"recap","Recap",[1108,2615,2616,2624,2631,2637],{},[1111,2617,2618,2619,2621,2622,1784],{},"A static factory method is a ",[1085,2620,1100],{}," method that returns an object, called in place of ",[1085,2623,1087],{},[1111,2625,2626,2627,2630],{},"Its name describes what the caller is getting (",[1085,2628,2629],{},"forAlliance","), and its logic decides which concrete class to build.",[1111,2632,2633,2634,2636],{},"It returns the interface type (",[1085,2635,1861],{},"), so callers depend only on the interface and never learn which class was picked.",[1111,2638,2639],{},"The decision lives in exactly one method, so every part of the code that needs an LED pattern gets the same logic without repeating it.",[1817,2641,1819],{},{"title":1139,"searchDepth":1152,"depth":1152,"links":2643},[2644,2645,2646,2647,2648,2649,2651,2652,2653,2654],{"id":1844,"depth":1152,"text":1845},{"id":1851,"depth":1152,"text":1852},{"id":1879,"depth":1152,"text":1880},{"id":1913,"depth":1152,"text":1914},{"id":2032,"depth":1152,"text":2033},{"id":2179,"depth":1152,"text":2650},"Step 5: Call It From main",{"id":2263,"depth":1152,"text":2264},{"id":2546,"depth":1152,"text":2547},{"id":2582,"depth":1152,"text":2583},{"id":2612,"depth":1152,"text":2613},{"outlineRef":1831,"pairsWith":2656,"status":2657},"[`lessons\u002Fch21-static-factories\u002F21-static-factories.md`](..\u002F..\u002Flessons\u002Fch21-static-factories\u002F21-static-factories.md)","new — authored worked example (fully solved, walked step by step — not a problem to attempt)",{"title":687,"description":1139},"USP5RYmZnabJlux7uOomunoKIdh_5JGZp7nWgEmig7g",{"id":2661,"title":1000,"body":2662,"description":1139,"extension":1829,"meta":4400,"navigation":1236,"path":999,"seo":4402,"stem":1001,"__hash__":4403},"exercises\u002Fshockwave-curriculum\u002Fexercises\u002Fch21-static-factories\u002F21-static-factories.md",{"type":1073,"value":2663,"toc":4395},[2664,2667,2671,2694,2699,2725,2731,2752,2776,2780,2807,2955,2988,2991,3084,3089,3282,3293,3379,3383,3389,3407,3452,3477,3489,3494,3758,3763,3768,3774,3779,3785,3790,3794,3800,3804,3810,3815,3819,3825,3829,3835,3840,3844,3850,3854,3860,3865,3869,3875,3879,3885,3890,3894,3900,3904,3910,3915,4334,4393],[1076,2665,1000],{"id":2666},"static-factories-exercises",[1080,2668,2670],{"id":2669},"multiple-choice","Multiple Choice",[1090,2672,2673,1116,2676,2679,2680,2683,2684,2687,2688,2690,2691,2693],{},[1094,2674,2675],{},"Question:",[1085,2677,2678],{},"Arm"," is an interface, and ",[1085,2681,2682],{},"RealArm"," and ",[1085,2685,2686],{},"SimArm"," both implement it. A teammate is writing a factory method that returns either a ",[1085,2689,2682],{}," or a ",[1085,2692,2686],{}," depending on whether the code is on the robot. Which method signature best follows this lesson's guidance?",[1090,2695,2696],{},[1094,2697,2698],{},"Options:",[1108,2700,2701,2707,2713,2719],{},[1111,2702,2703,2704],{},"A. ",[1085,2705,2706],{},"public static Arm createArm(boolean onRobot)",[1111,2708,2709,2710],{},"B. ",[1085,2711,2712],{},"public static RealArm createArm(boolean onRobot)",[1111,2714,2715,2716],{},"C. ",[1085,2717,2718],{},"public Arm createArm(boolean onRobot)",[1111,2720,2721,2722],{},"D. ",[1085,2723,2724],{},"public static void createArm(boolean onRobot)",[1090,2726,2727,2730],{},[1094,2728,2729],{},"Answer:"," A",[1090,2732,2733,2736,2737,2739,2740,2743,2744,2746,2747,2690,2749,2751],{},[1094,2734,2735],{},"Why:"," A static factory is ",[1085,2738,1100],{},", so callers can use the class name directly, and it returns the ",[1103,2741,2742],{},"interface"," type. Returning ",[1085,2745,2678],{}," lets the method hand back either a ",[1085,2748,2682],{},[1085,2750,2686],{},", and the caller never learns which one it got.",[1108,2753,2754,2763,2769],{},[1111,2755,2756,2757,2759,2760,2762],{},"B is wrong. With ",[1085,2758,2682],{}," as the return type, the method can't return a ",[1085,2761,2686],{}," at all (it won't compile), and every caller is locked into one concrete class. This is the lesson's \"returning a concrete class instead of an interface\" pitfall.",[1111,2764,2765,2766,2768],{},"C is wrong. Without ",[1085,2767,1289],{},", the method belongs to an object, so a caller would first need an instance of the factory class just to call it. Static factories are called directly on the class name.",[1111,2770,2771,2772,2775],{},"D is wrong. A factory's whole job is to return the object it built. A ",[1085,2773,2774],{},"void"," method can't hand anything back to the caller.",[1080,2777,2779],{"id":2778},"micro-parsons","Micro-Parsons",[1090,2781,2782,2785,2786,2789,2790,2793,2794,2683,2797,2800,2801,2804,2805,1784],{},[1094,2783,2784],{},"Problem:"," You're given everything in the program below except the ",[1085,2787,2788],{},"GripperFactory"," class: the ",[1085,2791,2792],{},"Gripper"," interface, its ",[1085,2795,2796],{},"RealGripper",[1085,2798,2799],{},"SimGripper"," implementations, and the ",[1085,2802,2803],{},"GripperDemo"," class with ",[1085,2806,1806],{},[1134,2808,2810],{"className":1136,"code":2809,"language":1138,"meta":1139,"style":1139},"public class GripperDemo\n{\n    public static void main(String[] args)\n    {\n        Gripper gripper = GripperFactory.createGripper(false);\n        System.out.println(gripper.status());\n    }\n}\n\ninterface Gripper\n{\n    String status();\n}\n\nclass RealGripper implements Gripper\n{\n    @Override\n    public String status()\n    {\n        return \"real gripper: reading the real sensor\";\n    }\n}\n\nclass SimGripper implements Gripper\n{\n    @Override\n    public String status()\n    {\n        return \"sim gripper: holding\";\n    }\n}\n\n\u002F\u002F GripperFactory class goes here\n",[1085,2811,2812,2817,2821,2825,2829,2834,2839,2843,2847,2851,2856,2860,2865,2869,2873,2878,2882,2886,2891,2895,2900,2904,2908,2912,2917,2921,2925,2929,2933,2938,2942,2946,2950],{"__ignoreMap":1139},[1143,2813,2814],{"class":1145,"line":1146},[1143,2815,2816],{},"public class GripperDemo\n",[1143,2818,2819],{"class":1145,"line":1152},[1143,2820,1155],{},[1143,2822,2823],{"class":1145,"line":1158},[1143,2824,2201],{},[1143,2826,2827],{"class":1145,"line":1164},[1143,2828,1167],{},[1143,2830,2831],{"class":1145,"line":1170},[1143,2832,2833],{},"        Gripper gripper = GripperFactory.createGripper(false);\n",[1143,2835,2836],{"class":1145,"line":1176},[1143,2837,2838],{},"        System.out.println(gripper.status());\n",[1143,2840,2841],{"class":1145,"line":1182},[1143,2842,1185],{},[1143,2844,2845],{"class":1145,"line":1188},[1143,2846,1191],{},[1143,2848,2849],{"class":1145,"line":1258},[1143,2850,1237],{"emptyLinePlaceholder":1236},[1143,2852,2853],{"class":1145,"line":1347},[1143,2854,2855],{},"interface Gripper\n",[1143,2857,2858],{"class":1145,"line":1352},[1143,2859,1155],{},[1143,2861,2862],{"class":1145,"line":1358},[1143,2863,2864],{},"    String status();\n",[1143,2866,2867],{"class":1145,"line":1363},[1143,2868,1191],{},[1143,2870,2871],{"class":1145,"line":1368},[1143,2872,1237],{"emptyLinePlaceholder":1236},[1143,2874,2875],{"class":1145,"line":1373},[1143,2876,2877],{},"class RealGripper implements Gripper\n",[1143,2879,2880],{"class":1145,"line":1379},[1143,2881,1155],{},[1143,2883,2884],{"class":1145,"line":1384},[1143,2885,1339],{},[1143,2887,2888],{"class":1145,"line":1389},[1143,2889,2890],{},"    public String status()\n",[1143,2892,2893],{"class":1145,"line":1394},[1143,2894,1167],{},[1143,2896,2897],{"class":1145,"line":1399},[1143,2898,2899],{},"        return \"real gripper: reading the real sensor\";\n",[1143,2901,2902],{"class":1145,"line":1405},[1143,2903,1185],{},[1143,2905,2906],{"class":1145,"line":1410},[1143,2907,1191],{},[1143,2909,2910],{"class":1145,"line":1415},[1143,2911,1237],{"emptyLinePlaceholder":1236},[1143,2913,2914],{"class":1145,"line":1420},[1143,2915,2916],{},"class SimGripper implements Gripper\n",[1143,2918,2919],{"class":1145,"line":1426},[1143,2920,1155],{},[1143,2922,2923],{"class":1145,"line":1431},[1143,2924,1339],{},[1143,2926,2927],{"class":1145,"line":1437},[1143,2928,2890],{},[1143,2930,2931],{"class":1145,"line":1442},[1143,2932,1167],{},[1143,2934,2935],{"class":1145,"line":1448},[1143,2936,2937],{},"        return \"sim gripper: holding\";\n",[1143,2939,2940],{"class":1145,"line":1453},[1143,2941,1185],{},[1143,2943,2944],{"class":1145,"line":1459},[1143,2945,1191],{},[1143,2947,2948],{"class":1145,"line":1465},[1143,2949,1237],{"emptyLinePlaceholder":1236},[1143,2951,2952],{"class":1145,"line":1471},[1143,2953,2954],{},"\u002F\u002F GripperFactory class goes here\n",[1090,2956,2957,2958,2960,2961,2963,2964,2967,2968,2971,2972,2974,2975,2977,2978,2980,2981,2984,2985,1784],{},"Reorder the fragments below into the ",[1085,2959,2788],{}," class. It holds one static factory method that returns a ",[1085,2962,2796],{}," when ",[1085,2965,2966],{},"onRobot"," is ",[1085,2969,2970],{},"true"," and a ",[1085,2973,2799],{}," otherwise, with ",[1085,2976,2792],{}," as the return type. ",[1085,2979,1806],{}," calls it with ",[1085,2982,2983],{},"false",", so the program prints ",[1085,2986,2987],{},"sim gripper: holding",[1090,2989,2990],{},"Reorder the fragments below to complete it:",[1108,2992,2993,3010,3016,3022,3028,3034,3040,3046,3052,3057,3063,3068],{},[1111,2994,2995,2996],{},"a.\n",[1134,2997,2999],{"className":1136,"code":2998,"language":1138,"meta":1139,"style":1139},"class GripperFactory\n{\n",[1085,3000,3001,3006],{"__ignoreMap":1139},[1143,3002,3003],{"class":1145,"line":1146},[1143,3004,3005],{},"class GripperFactory\n",[1143,3007,3008],{"class":1145,"line":1152},[1143,3009,1155],{},[1111,3011,3012,3013],{},"b. ",[1085,3014,3015],{},"    public static Gripper createGripper(boolean onRobot)",[1111,3017,3018,3019],{},"c. ",[1085,3020,3021],{},"    {",[1111,3023,3024,3025],{},"d. ",[1085,3026,3027],{},"        if (onRobot)",[1111,3029,3030,3031],{},"e. ",[1085,3032,3033],{},"        {",[1111,3035,3036,3037],{},"f. ",[1085,3038,3039],{},"            return new RealGripper();",[1111,3041,3042,3043],{},"g. ",[1085,3044,3045],{},"        }",[1111,3047,3048,3049],{},"h. ",[1085,3050,3051],{},"        else",[1111,3053,3054,3055],{},"i. ",[1085,3056,3033],{},[1111,3058,3059,3060],{},"j. ",[1085,3061,3062],{},"            return new SimGripper();",[1111,3064,3065,3066],{},"k. ",[1085,3067,3045],{},[1111,3069,3070,3071],{},"l.\n",[1134,3072,3074],{"className":1136,"code":3073,"language":1138,"meta":1139,"style":1139},"    }\n}\n",[1085,3075,3076,3080],{"__ignoreMap":1139},[1143,3077,3078],{"class":1145,"line":1146},[1143,3079,1185],{},[1143,3081,3082],{"class":1145,"line":1152},[1143,3083,1191],{},[1090,3085,3086,3088],{},[1094,3087,2729],{}," a, b, c, d, e, f, g, h, i, j, k, l",[1134,3090,3092],{"className":1136,"code":3091,"language":1138,"meta":1139,"style":1139},"public class GripperDemo\n{\n    public static void main(String[] args)\n    {\n        Gripper gripper = GripperFactory.createGripper(false);\n        System.out.println(gripper.status());\n    }\n}\n\ninterface Gripper\n{\n    String status();\n}\n\nclass RealGripper implements Gripper\n{\n    @Override\n    public String status()\n    {\n        return \"real gripper: reading the real sensor\";\n    }\n}\n\nclass SimGripper implements Gripper\n{\n    @Override\n    public String status()\n    {\n        return \"sim gripper: holding\";\n    }\n}\n\nclass GripperFactory\n{\n    public static Gripper createGripper(boolean onRobot)\n    {\n        if (onRobot)\n        {\n            return new RealGripper();\n        }\n        else\n        {\n            return new SimGripper();\n        }\n    }\n}\n",[1085,3093,3094,3098,3102,3106,3110,3114,3118,3122,3126,3130,3134,3138,3142,3146,3150,3154,3158,3162,3166,3170,3174,3178,3182,3186,3190,3194,3198,3202,3206,3210,3214,3218,3222,3226,3230,3235,3239,3244,3248,3253,3257,3261,3265,3270,3274,3278],{"__ignoreMap":1139},[1143,3095,3096],{"class":1145,"line":1146},[1143,3097,2816],{},[1143,3099,3100],{"class":1145,"line":1152},[1143,3101,1155],{},[1143,3103,3104],{"class":1145,"line":1158},[1143,3105,2201],{},[1143,3107,3108],{"class":1145,"line":1164},[1143,3109,1167],{},[1143,3111,3112],{"class":1145,"line":1170},[1143,3113,2833],{},[1143,3115,3116],{"class":1145,"line":1176},[1143,3117,2838],{},[1143,3119,3120],{"class":1145,"line":1182},[1143,3121,1185],{},[1143,3123,3124],{"class":1145,"line":1188},[1143,3125,1191],{},[1143,3127,3128],{"class":1145,"line":1258},[1143,3129,1237],{"emptyLinePlaceholder":1236},[1143,3131,3132],{"class":1145,"line":1347},[1143,3133,2855],{},[1143,3135,3136],{"class":1145,"line":1352},[1143,3137,1155],{},[1143,3139,3140],{"class":1145,"line":1358},[1143,3141,2864],{},[1143,3143,3144],{"class":1145,"line":1363},[1143,3145,1191],{},[1143,3147,3148],{"class":1145,"line":1368},[1143,3149,1237],{"emptyLinePlaceholder":1236},[1143,3151,3152],{"class":1145,"line":1373},[1143,3153,2877],{},[1143,3155,3156],{"class":1145,"line":1379},[1143,3157,1155],{},[1143,3159,3160],{"class":1145,"line":1384},[1143,3161,1339],{},[1143,3163,3164],{"class":1145,"line":1389},[1143,3165,2890],{},[1143,3167,3168],{"class":1145,"line":1394},[1143,3169,1167],{},[1143,3171,3172],{"class":1145,"line":1399},[1143,3173,2899],{},[1143,3175,3176],{"class":1145,"line":1405},[1143,3177,1185],{},[1143,3179,3180],{"class":1145,"line":1410},[1143,3181,1191],{},[1143,3183,3184],{"class":1145,"line":1415},[1143,3185,1237],{"emptyLinePlaceholder":1236},[1143,3187,3188],{"class":1145,"line":1420},[1143,3189,2916],{},[1143,3191,3192],{"class":1145,"line":1426},[1143,3193,1155],{},[1143,3195,3196],{"class":1145,"line":1431},[1143,3197,1339],{},[1143,3199,3200],{"class":1145,"line":1437},[1143,3201,2890],{},[1143,3203,3204],{"class":1145,"line":1442},[1143,3205,1167],{},[1143,3207,3208],{"class":1145,"line":1448},[1143,3209,2937],{},[1143,3211,3212],{"class":1145,"line":1453},[1143,3213,1185],{},[1143,3215,3216],{"class":1145,"line":1459},[1143,3217,1191],{},[1143,3219,3220],{"class":1145,"line":1465},[1143,3221,1237],{"emptyLinePlaceholder":1236},[1143,3223,3224],{"class":1145,"line":1471},[1143,3225,3005],{},[1143,3227,3228],{"class":1145,"line":1477},[1143,3229,1155],{},[1143,3231,3232],{"class":1145,"line":1483},[1143,3233,3234],{},"    public static Gripper createGripper(boolean onRobot)\n",[1143,3236,3237],{"class":1145,"line":1488},[1143,3238,1167],{},[1143,3240,3241],{"class":1145,"line":1494},[1143,3242,3243],{},"        if (onRobot)\n",[1143,3245,3246],{"class":1145,"line":1499},[1143,3247,1462],{},[1143,3249,3250],{"class":1145,"line":1504},[1143,3251,3252],{},"            return new RealGripper();\n",[1143,3254,3255],{"class":1145,"line":2441},[1143,3256,1474],{},[1143,3258,3259],{"class":1145,"line":2446},[1143,3260,1480],{},[1143,3262,3263],{"class":1145,"line":2451},[1143,3264,1462],{},[1143,3266,3267],{"class":1145,"line":2456},[1143,3268,3269],{},"            return new SimGripper();\n",[1143,3271,3272],{"class":1145,"line":2461},[1143,3273,1474],{},[1143,3275,3276],{"class":1145,"line":2466},[1143,3277,1185],{},[1143,3279,3280],{"class":1145,"line":2471},[1143,3281,1191],{},[1090,3283,3284,3285,2270,3287,3289,3290,3292],{},"(",[1085,3286,2803],{},[1085,3288,1806],{},", comes first in the file — on Java 17, ",[1085,3291,2276],{}," source-launch only runs the first class in the file; Java 25 is more lenient, but leading with the public class works on both.)",[1090,3294,3295,3298,3299,3302,3303,3306,3307,3309,3310,3312,3313,3316,3317,3319,3320,3322,3323,3326,3327,1807,3329,3332,3333,3332,3336,3332,3339,3342,3343,1807,3345,3332,3348,3332,3351,3332,3354,3357,3358,3360,3361,3363,3364,3367,3368,3370,3371,3373,3374,2250,3376,3378],{},[1094,3296,3297],{},"Why this order:"," The class line and its opening brace (",[1085,3300,3301],{},"a",", merged — two lines with nothing valid between them) come first. Then the factory method's signature (",[1085,3304,3305],{},"b","), which is ",[1085,3308,1100],{}," so ",[1085,3311,1806],{}," can call it as ",[1085,3314,3315],{},"GripperFactory.createGripper(...)"," without any ",[1085,3318,2788],{}," object, and which returns the interface type ",[1085,3321,2792],{}," so it's free to hand back either implementation. The method's opening brace (",[1085,3324,3325],{},"c",") follows. Inside, the braced ",[1085,3328,1735],{},[1085,3330,3331],{},"d",", ",[1085,3334,3335],{},"e",[1085,3337,3338],{},"f",[1085,3340,3341],{},"g",") has to come before its matching ",[1085,3344,2576],{},[1085,3346,3347],{},"h",[1085,3349,3350],{},"i",[1085,3352,3353],{},"j",[1085,3355,3356],{},"k",") — every ",[1085,3359,1735],{},"\u002F",[1085,3362,2576],{}," here uses braces (Lesson 5.1). Together they're the one place the real-vs-simulated decision is made. The trailing braces close in reverse, the method's then the class's, merged into one fragment (",[1085,3365,3366],{},"l",") since nothing valid can go between two closing braces. ",[1085,3369,1806],{}," only ever sees a ",[1085,3372,2792],{},", and never mentions ",[1085,3375,2796],{},[1085,3377,2799],{}," itself.",[1080,3380,3382],{"id":3381},"coding","Coding",[1090,3384,3385,3388],{},[1094,3386,3387],{},"Mode:"," full-program",[1090,3390,3391,3393,3394,3396,3397,3332,3400,3332,3403,3406],{},[1094,3392,2784],{}," Write two classes that use static factory methods. The interface ",[1085,3395,1726],{}," and its three implementations\n(",[1085,3398,3399],{},"RealDrivetrain",[1085,3401,3402],{},"PracticeDrivetrain",[1085,3404,3405],{},"SimDrivetrain",") are given.",[1090,3408,3409,3414,3415,3417,3418,3421,3422,1116,3424,3426,3427,3430,3431,3434,3435,3332,3437,3434,3440,3442,3443,3448,3449,3451],{},[1094,3410,3411],{},[1085,3412,3413],{},"DrivetrainFactory"," is a factory-only class: it has a ",[1085,3416,1293],{}," constructor and one method,\n",[1085,3419,3420],{},"public static Drivetrain create(String mode)",". It uses a ",[1085,3423,1562],{},[1094,3425,1565],{}," on ",[1085,3428,3429],{},"mode",":\n",[1085,3432,3433],{},"\"real\""," gives a ",[1085,3436,3399],{},[1085,3438,3439],{},"\"practice\"",[1085,3441,3402],{},", and anything else, ",[1094,3444,3445,3446],{},"including ",[1085,3447,1678],{}," (nothing selected),\ngives a ",[1085,3450,3405],{},". The return type is the interface, not a concrete class.",[1090,3453,3454,3458,3459,3461,3462,3465,3466,3468,3469,3472,3473,3476],{},[1094,3455,3456],{},[1085,3457,1270],{}," is a cached instance. Its constructor is ",[1085,3460,1293],{},"; ",[1085,3463,3464],{},"public static SensorLog getInstance()"," always returns the\n",[1094,3467,1211],{}," object. ",[1085,3470,3471],{},"void record(String entry)"," adds one to a counter and ",[1085,3474,3475],{},"int getCount()"," returns it (the entry text itself isn't stored).",[1090,3478,3479,3481,3482,3485,3486,3488],{},[1085,3480,1806],{}," reads a count, then that many modes (the word ",[1085,3483,3484],{},"none"," is turned into ",[1085,3487,1678],{},").",[1090,3490,3491],{},[1094,3492,3493],{},"Starter:",[1134,3495,3497],{"className":1136,"code":3496,"language":1138,"meta":1139,"style":1139},"import java.util.Scanner;\n\npublic class Main\n{\n    public static void main(String[] args) \u002F\u002F Don't change main\n    {\n        Scanner in = new Scanner(System.in);\n        int count = in.nextInt();\n        for (int i = 0; i \u003C count; i++)\n        {\n            String mode = in.next();\n            if (mode.equals(\"none\"))\n            {\n                mode = null; \u002F\u002F nothing was selected\n            }\n            Drivetrain drivetrain = DrivetrainFactory.create(mode);\n            System.out.println(mode + \" -> \" + drivetrain.describe());\n            SensorLog.getInstance().record(mode);\n        }\n        SensorLog first = SensorLog.getInstance();\n        SensorLog second = SensorLog.getInstance();\n        System.out.println(\"Same log: \" + (first == second));\n        System.out.println(\"Entries: \" + first.getCount());\n    }\n}\n\ninterface Drivetrain\n{\n    String describe();\n}\n\nclass RealDrivetrain implements Drivetrain\n{\n    public String describe()\n    {\n        return \"real motors\";\n    }\n}\n\nclass PracticeDrivetrain implements Drivetrain\n{\n    public String describe()\n    {\n        return \"practice bot\";\n    }\n}\n\nclass SimDrivetrain implements Drivetrain\n{\n    public String describe()\n    {\n        return \"simulation\";\n    }\n}\n\n\u002F\u002F TODO: write the class DrivetrainFactory\n\n\u002F\u002F TODO: write the class SensorLog\n",[1085,3498,3499,3504,3508,3513,3517,3522,3526,3531,3536,3541,3545,3550,3555,3560,3565,3570,3575,3580,3585,3589,3594,3599,3604,3609,3613,3617,3621,3626,3630,3634,3638,3642,3647,3651,3655,3659,3664,3668,3672,3676,3681,3685,3689,3693,3698,3702,3706,3710,3715,3719,3723,3727,3732,3736,3740,3744,3749,3753],{"__ignoreMap":1139},[1143,3500,3501],{"class":1145,"line":1146},[1143,3502,3503],{},"import java.util.Scanner;\n",[1143,3505,3506],{"class":1145,"line":1152},[1143,3507,1237],{"emptyLinePlaceholder":1236},[1143,3509,3510],{"class":1145,"line":1158},[1143,3511,3512],{},"public class Main\n",[1143,3514,3515],{"class":1145,"line":1164},[1143,3516,1155],{},[1143,3518,3519],{"class":1145,"line":1170},[1143,3520,3521],{},"    public static void main(String[] args) \u002F\u002F Don't change main\n",[1143,3523,3524],{"class":1145,"line":1176},[1143,3525,1167],{},[1143,3527,3528],{"class":1145,"line":1182},[1143,3529,3530],{},"        Scanner in = new Scanner(System.in);\n",[1143,3532,3533],{"class":1145,"line":1188},[1143,3534,3535],{},"        int count = in.nextInt();\n",[1143,3537,3538],{"class":1145,"line":1258},[1143,3539,3540],{},"        for (int i = 0; i \u003C count; i++)\n",[1143,3542,3543],{"class":1145,"line":1347},[1143,3544,1462],{},[1143,3546,3547],{"class":1145,"line":1352},[1143,3548,3549],{},"            String mode = in.next();\n",[1143,3551,3552],{"class":1145,"line":1358},[1143,3553,3554],{},"            if (mode.equals(\"none\"))\n",[1143,3556,3557],{"class":1145,"line":1363},[1143,3558,3559],{},"            {\n",[1143,3561,3562],{"class":1145,"line":1368},[1143,3563,3564],{},"                mode = null; \u002F\u002F nothing was selected\n",[1143,3566,3567],{"class":1145,"line":1373},[1143,3568,3569],{},"            }\n",[1143,3571,3572],{"class":1145,"line":1379},[1143,3573,3574],{},"            Drivetrain drivetrain = DrivetrainFactory.create(mode);\n",[1143,3576,3577],{"class":1145,"line":1384},[1143,3578,3579],{},"            System.out.println(mode + \" -> \" + drivetrain.describe());\n",[1143,3581,3582],{"class":1145,"line":1389},[1143,3583,3584],{},"            SensorLog.getInstance().record(mode);\n",[1143,3586,3587],{"class":1145,"line":1394},[1143,3588,1474],{},[1143,3590,3591],{"class":1145,"line":1399},[1143,3592,3593],{},"        SensorLog first = SensorLog.getInstance();\n",[1143,3595,3596],{"class":1145,"line":1405},[1143,3597,3598],{},"        SensorLog second = SensorLog.getInstance();\n",[1143,3600,3601],{"class":1145,"line":1410},[1143,3602,3603],{},"        System.out.println(\"Same log: \" + (first == second));\n",[1143,3605,3606],{"class":1145,"line":1415},[1143,3607,3608],{},"        System.out.println(\"Entries: \" + first.getCount());\n",[1143,3610,3611],{"class":1145,"line":1420},[1143,3612,1185],{},[1143,3614,3615],{"class":1145,"line":1426},[1143,3616,1191],{},[1143,3618,3619],{"class":1145,"line":1431},[1143,3620,1237],{"emptyLinePlaceholder":1236},[1143,3622,3623],{"class":1145,"line":1437},[1143,3624,3625],{},"interface Drivetrain\n",[1143,3627,3628],{"class":1145,"line":1442},[1143,3629,1155],{},[1143,3631,3632],{"class":1145,"line":1448},[1143,3633,1899],{},[1143,3635,3636],{"class":1145,"line":1453},[1143,3637,1191],{},[1143,3639,3640],{"class":1145,"line":1459},[1143,3641,1237],{"emptyLinePlaceholder":1236},[1143,3643,3644],{"class":1145,"line":1465},[1143,3645,3646],{},"class RealDrivetrain implements Drivetrain\n",[1143,3648,3649],{"class":1145,"line":1471},[1143,3650,1155],{},[1143,3652,3653],{"class":1145,"line":1477},[1143,3654,1968],{},[1143,3656,3657],{"class":1145,"line":1483},[1143,3658,1167],{},[1143,3660,3661],{"class":1145,"line":1488},[1143,3662,3663],{},"        return \"real motors\";\n",[1143,3665,3666],{"class":1145,"line":1494},[1143,3667,1185],{},[1143,3669,3670],{"class":1145,"line":1499},[1143,3671,1191],{},[1143,3673,3674],{"class":1145,"line":1504},[1143,3675,1237],{"emptyLinePlaceholder":1236},[1143,3677,3678],{"class":1145,"line":2441},[1143,3679,3680],{},"class PracticeDrivetrain implements Drivetrain\n",[1143,3682,3683],{"class":1145,"line":2446},[1143,3684,1155],{},[1143,3686,3687],{"class":1145,"line":2451},[1143,3688,1968],{},[1143,3690,3691],{"class":1145,"line":2456},[1143,3692,1167],{},[1143,3694,3695],{"class":1145,"line":2461},[1143,3696,3697],{},"        return \"practice bot\";\n",[1143,3699,3700],{"class":1145,"line":2466},[1143,3701,1185],{},[1143,3703,3704],{"class":1145,"line":2471},[1143,3705,1191],{},[1143,3707,3708],{"class":1145,"line":2476},[1143,3709,1237],{"emptyLinePlaceholder":1236},[1143,3711,3712],{"class":1145,"line":2481},[1143,3713,3714],{},"class SimDrivetrain implements Drivetrain\n",[1143,3716,3717],{"class":1145,"line":2486},[1143,3718,1155],{},[1143,3720,3721],{"class":1145,"line":2491},[1143,3722,1968],{},[1143,3724,3725],{"class":1145,"line":2496},[1143,3726,1167],{},[1143,3728,3729],{"class":1145,"line":2501},[1143,3730,3731],{},"        return \"simulation\";\n",[1143,3733,3734],{"class":1145,"line":2506},[1143,3735,1185],{},[1143,3737,3738],{"class":1145,"line":2511},[1143,3739,1191],{},[1143,3741,3742],{"class":1145,"line":2516},[1143,3743,1237],{"emptyLinePlaceholder":1236},[1143,3745,3746],{"class":1145,"line":2521},[1143,3747,3748],{},"\u002F\u002F TODO: write the class DrivetrainFactory\n",[1143,3750,3751],{"class":1145,"line":2526},[1143,3752,1237],{"emptyLinePlaceholder":1236},[1143,3754,3755],{"class":1145,"line":2531},[1143,3756,3757],{},"\u002F\u002F TODO: write the class SensorLog\n",[1090,3759,3760],{},[1094,3761,3762],{},"Scenario 1 (visible):",[1090,3764,3765],{},[1094,3766,3767],{},"Input:",[1134,3769,3772],{"className":3770,"code":3771,"language":2553,"meta":1139},[2551],"3\nreal\nsim\npractice\n",[1085,3773,3771],{"__ignoreMap":1139},[1090,3775,3776],{},[1094,3777,3778],{},"Expected output:",[1134,3780,3783],{"className":3781,"code":3782,"language":2553,"meta":1139},[2551],"real -> real motors\nsim -> simulation\npractice -> practice bot\nSame log: true\nEntries: 3\n",[1085,3784,3782],{"__ignoreMap":1139},[1090,3786,3787],{},[1094,3788,3789],{},"Scenario 2 (visible):",[1090,3791,3792],{},[1094,3793,3767],{},[1134,3795,3798],{"className":3796,"code":3797,"language":2553,"meta":1139},[2551],"2\nreal\nreal\n",[1085,3799,3797],{"__ignoreMap":1139},[1090,3801,3802],{},[1094,3803,3778],{},[1134,3805,3808],{"className":3806,"code":3807,"language":2553,"meta":1139},[2551],"real -> real motors\nreal -> real motors\nSame log: true\nEntries: 2\n",[1085,3809,3807],{"__ignoreMap":1139},[1090,3811,3812],{},[1094,3813,3814],{},"Scenario 3 (visible):",[1090,3816,3817],{},[1094,3818,3767],{},[1134,3820,3823],{"className":3821,"code":3822,"language":2553,"meta":1139},[2551],"1\ntank\n",[1085,3824,3822],{"__ignoreMap":1139},[1090,3826,3827],{},[1094,3828,3778],{},[1134,3830,3833],{"className":3831,"code":3832,"language":2553,"meta":1139},[2551],"tank -> simulation\nSame log: true\nEntries: 1\n",[1085,3834,3832],{"__ignoreMap":1139},[1090,3836,3837],{},[1094,3838,3839],{},"Scenario 4 (hidden):",[1090,3841,3842],{},[1094,3843,3767],{},[1134,3845,3848],{"className":3846,"code":3847,"language":2553,"meta":1139},[2551],"3\nnone\nreal\nnone\n",[1085,3849,3847],{"__ignoreMap":1139},[1090,3851,3852],{},[1094,3853,3778],{},[1134,3855,3858],{"className":3856,"code":3857,"language":2553,"meta":1139},[2551],"null -> simulation\nreal -> real motors\nnull -> simulation\nSame log: true\nEntries: 3\n",[1085,3859,3857],{"__ignoreMap":1139},[1090,3861,3862],{},[1094,3863,3864],{},"Scenario 5 (hidden):",[1090,3866,3867],{},[1094,3868,3767],{},[1134,3870,3873],{"className":3871,"code":3872,"language":2553,"meta":1139},[2551],"2\nREAL\npractice\n",[1085,3874,3872],{"__ignoreMap":1139},[1090,3876,3877],{},[1094,3878,3778],{},[1134,3880,3883],{"className":3881,"code":3882,"language":2553,"meta":1139},[2551],"REAL -> simulation\npractice -> practice bot\nSame log: true\nEntries: 2\n",[1085,3884,3882],{"__ignoreMap":1139},[1090,3886,3887],{},[1094,3888,3889],{},"Scenario 6 (hidden):",[1090,3891,3892],{},[1094,3893,3767],{},[1134,3895,3898],{"className":3896,"code":3897,"language":2553,"meta":1139},[2551],"1\nnone\n",[1085,3899,3897],{"__ignoreMap":1139},[1090,3901,3902],{},[1094,3903,3778],{},[1134,3905,3908],{"className":3906,"code":3907,"language":2553,"meta":1139},[2551],"null -> simulation\nSame log: true\nEntries: 1\n",[1085,3909,3907],{"__ignoreMap":1139},[1090,3911,3912],{},[1094,3913,3914],{},"Solution:",[1134,3916,3918],{"className":1136,"code":3917,"language":1138,"meta":1139,"style":1139},"import java.util.Scanner;\n\npublic class Main\n{\n    public static void main(String[] args) \u002F\u002F Don't change main\n    {\n        Scanner in = new Scanner(System.in);\n        int count = in.nextInt();\n        for (int i = 0; i \u003C count; i++)\n        {\n            String mode = in.next();\n            if (mode.equals(\"none\"))\n            {\n                mode = null; \u002F\u002F nothing was selected\n            }\n            Drivetrain drivetrain = DrivetrainFactory.create(mode);\n            System.out.println(mode + \" -> \" + drivetrain.describe());\n            SensorLog.getInstance().record(mode);\n        }\n        SensorLog first = SensorLog.getInstance();\n        SensorLog second = SensorLog.getInstance();\n        System.out.println(\"Same log: \" + (first == second));\n        System.out.println(\"Entries: \" + first.getCount());\n    }\n}\n\ninterface Drivetrain\n{\n    String describe();\n}\n\nclass RealDrivetrain implements Drivetrain\n{\n    public String describe()\n    {\n        return \"real motors\";\n    }\n}\n\nclass PracticeDrivetrain implements Drivetrain\n{\n    public String describe()\n    {\n        return \"practice bot\";\n    }\n}\n\nclass SimDrivetrain implements Drivetrain\n{\n    public String describe()\n    {\n        return \"simulation\";\n    }\n}\n\nclass DrivetrainFactory\n{\n    private DrivetrainFactory() {}\n\n    public static Drivetrain create(String mode)\n    {\n        return switch (mode)\n        {\n            case \"real\" -> new RealDrivetrain();\n            case \"practice\" -> new PracticeDrivetrain();\n            case null, default -> new SimDrivetrain();\n        };\n    }\n}\n\nclass SensorLog\n{\n    private static final SensorLog INSTANCE = new SensorLog();\n    private int count = 0;\n\n    private SensorLog() {}\n\n    public static SensorLog getInstance()\n    {\n        return INSTANCE;\n    }\n\n    public void record(String entry)\n    {\n        count++;\n    }\n\n    public int getCount()\n    {\n        return count;\n    }\n}\n",[1085,3919,3920,3924,3928,3932,3936,3940,3944,3948,3952,3956,3960,3964,3968,3972,3976,3980,3984,3988,3992,3996,4000,4004,4008,4012,4016,4020,4024,4028,4032,4036,4040,4044,4048,4052,4056,4060,4064,4068,4072,4076,4080,4084,4088,4092,4096,4100,4104,4108,4112,4116,4120,4124,4128,4132,4136,4140,4145,4149,4154,4158,4163,4168,4173,4178,4184,4190,4196,4201,4206,4211,4216,4222,4227,4232,4238,4243,4249,4254,4259,4264,4270,4275,4280,4286,4291,4297,4302,4307,4313,4318,4324,4329],{"__ignoreMap":1139},[1143,3921,3922],{"class":1145,"line":1146},[1143,3923,3503],{},[1143,3925,3926],{"class":1145,"line":1152},[1143,3927,1237],{"emptyLinePlaceholder":1236},[1143,3929,3930],{"class":1145,"line":1158},[1143,3931,3512],{},[1143,3933,3934],{"class":1145,"line":1164},[1143,3935,1155],{},[1143,3937,3938],{"class":1145,"line":1170},[1143,3939,3521],{},[1143,3941,3942],{"class":1145,"line":1176},[1143,3943,1167],{},[1143,3945,3946],{"class":1145,"line":1182},[1143,3947,3530],{},[1143,3949,3950],{"class":1145,"line":1188},[1143,3951,3535],{},[1143,3953,3954],{"class":1145,"line":1258},[1143,3955,3540],{},[1143,3957,3958],{"class":1145,"line":1347},[1143,3959,1462],{},[1143,3961,3962],{"class":1145,"line":1352},[1143,3963,3549],{},[1143,3965,3966],{"class":1145,"line":1358},[1143,3967,3554],{},[1143,3969,3970],{"class":1145,"line":1363},[1143,3971,3559],{},[1143,3973,3974],{"class":1145,"line":1368},[1143,3975,3564],{},[1143,3977,3978],{"class":1145,"line":1373},[1143,3979,3569],{},[1143,3981,3982],{"class":1145,"line":1379},[1143,3983,3574],{},[1143,3985,3986],{"class":1145,"line":1384},[1143,3987,3579],{},[1143,3989,3990],{"class":1145,"line":1389},[1143,3991,3584],{},[1143,3993,3994],{"class":1145,"line":1394},[1143,3995,1474],{},[1143,3997,3998],{"class":1145,"line":1399},[1143,3999,3593],{},[1143,4001,4002],{"class":1145,"line":1405},[1143,4003,3598],{},[1143,4005,4006],{"class":1145,"line":1410},[1143,4007,3603],{},[1143,4009,4010],{"class":1145,"line":1415},[1143,4011,3608],{},[1143,4013,4014],{"class":1145,"line":1420},[1143,4015,1185],{},[1143,4017,4018],{"class":1145,"line":1426},[1143,4019,1191],{},[1143,4021,4022],{"class":1145,"line":1431},[1143,4023,1237],{"emptyLinePlaceholder":1236},[1143,4025,4026],{"class":1145,"line":1437},[1143,4027,3625],{},[1143,4029,4030],{"class":1145,"line":1442},[1143,4031,1155],{},[1143,4033,4034],{"class":1145,"line":1448},[1143,4035,1899],{},[1143,4037,4038],{"class":1145,"line":1453},[1143,4039,1191],{},[1143,4041,4042],{"class":1145,"line":1459},[1143,4043,1237],{"emptyLinePlaceholder":1236},[1143,4045,4046],{"class":1145,"line":1465},[1143,4047,3646],{},[1143,4049,4050],{"class":1145,"line":1471},[1143,4051,1155],{},[1143,4053,4054],{"class":1145,"line":1477},[1143,4055,1968],{},[1143,4057,4058],{"class":1145,"line":1483},[1143,4059,1167],{},[1143,4061,4062],{"class":1145,"line":1488},[1143,4063,3663],{},[1143,4065,4066],{"class":1145,"line":1494},[1143,4067,1185],{},[1143,4069,4070],{"class":1145,"line":1499},[1143,4071,1191],{},[1143,4073,4074],{"class":1145,"line":1504},[1143,4075,1237],{"emptyLinePlaceholder":1236},[1143,4077,4078],{"class":1145,"line":2441},[1143,4079,3680],{},[1143,4081,4082],{"class":1145,"line":2446},[1143,4083,1155],{},[1143,4085,4086],{"class":1145,"line":2451},[1143,4087,1968],{},[1143,4089,4090],{"class":1145,"line":2456},[1143,4091,1167],{},[1143,4093,4094],{"class":1145,"line":2461},[1143,4095,3697],{},[1143,4097,4098],{"class":1145,"line":2466},[1143,4099,1185],{},[1143,4101,4102],{"class":1145,"line":2471},[1143,4103,1191],{},[1143,4105,4106],{"class":1145,"line":2476},[1143,4107,1237],{"emptyLinePlaceholder":1236},[1143,4109,4110],{"class":1145,"line":2481},[1143,4111,3714],{},[1143,4113,4114],{"class":1145,"line":2486},[1143,4115,1155],{},[1143,4117,4118],{"class":1145,"line":2491},[1143,4119,1968],{},[1143,4121,4122],{"class":1145,"line":2496},[1143,4123,1167],{},[1143,4125,4126],{"class":1145,"line":2501},[1143,4127,3731],{},[1143,4129,4130],{"class":1145,"line":2506},[1143,4131,1185],{},[1143,4133,4134],{"class":1145,"line":2511},[1143,4135,1191],{},[1143,4137,4138],{"class":1145,"line":2516},[1143,4139,1237],{"emptyLinePlaceholder":1236},[1143,4141,4142],{"class":1145,"line":2521},[1143,4143,4144],{},"class DrivetrainFactory\n",[1143,4146,4147],{"class":1145,"line":2526},[1143,4148,1155],{},[1143,4150,4151],{"class":1145,"line":2531},[1143,4152,4153],{},"    private DrivetrainFactory() {}\n",[1143,4155,4156],{"class":1145,"line":2536},[1143,4157,1237],{"emptyLinePlaceholder":1236},[1143,4159,4160],{"class":1145,"line":2541},[1143,4161,4162],{},"    public static Drivetrain create(String mode)\n",[1143,4164,4166],{"class":1145,"line":4165},61,[1143,4167,1167],{},[1143,4169,4171],{"class":1145,"line":4170},62,[1143,4172,1598],{},[1143,4174,4176],{"class":1145,"line":4175},63,[1143,4177,1462],{},[1143,4179,4181],{"class":1145,"line":4180},64,[1143,4182,4183],{},"            case \"real\" -> new RealDrivetrain();\n",[1143,4185,4187],{"class":1145,"line":4186},65,[1143,4188,4189],{},"            case \"practice\" -> new PracticeDrivetrain();\n",[1143,4191,4193],{"class":1145,"line":4192},66,[1143,4194,4195],{},"            case null, default -> new SimDrivetrain();\n",[1143,4197,4199],{"class":1145,"line":4198},67,[1143,4200,1627],{},[1143,4202,4204],{"class":1145,"line":4203},68,[1143,4205,1185],{},[1143,4207,4209],{"class":1145,"line":4208},69,[1143,4210,1191],{},[1143,4212,4214],{"class":1145,"line":4213},70,[1143,4215,1237],{"emptyLinePlaceholder":1236},[1143,4217,4219],{"class":1145,"line":4218},71,[1143,4220,4221],{},"class SensorLog\n",[1143,4223,4225],{"class":1145,"line":4224},72,[1143,4226,1155],{},[1143,4228,4230],{"class":1145,"line":4229},73,[1143,4231,1231],{},[1143,4233,4235],{"class":1145,"line":4234},74,[1143,4236,4237],{},"    private int count = 0;\n",[1143,4239,4241],{"class":1145,"line":4240},75,[1143,4242,1237],{"emptyLinePlaceholder":1236},[1143,4244,4246],{"class":1145,"line":4245},76,[1143,4247,4248],{},"    private SensorLog() {}\n",[1143,4250,4252],{"class":1145,"line":4251},77,[1143,4253,1237],{"emptyLinePlaceholder":1236},[1143,4255,4257],{"class":1145,"line":4256},78,[1143,4258,1242],{},[1143,4260,4262],{"class":1145,"line":4261},79,[1143,4263,1167],{},[1143,4265,4267],{"class":1145,"line":4266},80,[1143,4268,4269],{},"        return INSTANCE;\n",[1143,4271,4273],{"class":1145,"line":4272},81,[1143,4274,1185],{},[1143,4276,4278],{"class":1145,"line":4277},82,[1143,4279,1237],{"emptyLinePlaceholder":1236},[1143,4281,4283],{"class":1145,"line":4282},83,[1143,4284,4285],{},"    public void record(String entry)\n",[1143,4287,4289],{"class":1145,"line":4288},84,[1143,4290,1167],{},[1143,4292,4294],{"class":1145,"line":4293},85,[1143,4295,4296],{},"        count++;\n",[1143,4298,4300],{"class":1145,"line":4299},86,[1143,4301,1185],{},[1143,4303,4305],{"class":1145,"line":4304},87,[1143,4306,1237],{"emptyLinePlaceholder":1236},[1143,4308,4310],{"class":1145,"line":4309},88,[1143,4311,4312],{},"    public int getCount()\n",[1143,4314,4316],{"class":1145,"line":4315},89,[1143,4317,1167],{},[1143,4319,4321],{"class":1145,"line":4320},90,[1143,4322,4323],{},"        return count;\n",[1143,4325,4327],{"class":1145,"line":4326},91,[1143,4328,1185],{},[1143,4330,4332],{"class":1145,"line":4331},92,[1143,4333,1191],{},[1090,4335,4336,1116,4338,4340,4341,4343,4344,1694,4346,4348,4349,4351,4352,4354,4355,4357,4358,4360,4361,4363,4364,4367,4368,4371,4372,4375,4376,2683,4378,4375,4381,4384,4385,4388,4389,4392],{},[1094,4337,2735],{},[1085,4339,3413],{}," is the lesson's \"choose an implementation by condition\" factory: the caller never names a concrete class, and the return type is the interface.\nA plain ",[1085,4342,1690],{}," doesn't catch ",[1085,4345,1678],{},[1085,4347,1678],{}," string throws ",[1085,4350,1700],{},", so ",[1085,4353,1704],{}," is what makes the ",[1085,4356,3484],{}," scenarios work.\n",[1085,4359,1270],{}," shows the other payoff of a factory: it returns the ",[1103,4362,1211],{}," cached object every call. A ",[1085,4365,4366],{},"getInstance()"," that writes ",[1085,4369,4370],{},"return new SensorLog();"," still compiles, but\n",[1085,4373,4374],{},"Same log"," prints ",[1085,4377,2983],{},[1085,4379,4380],{},"Entries",[1085,4382,4383],{},"0",". Writing only ",[1085,4386,4387],{},"default ->"," (no ",[1085,4390,4391],{},"case null",") crashes on the hidden scenarios that select nothing.",[1817,4394,1819],{},{"title":1139,"searchDepth":1152,"depth":1152,"links":4396},[4397,4398,4399],{"id":2669,"depth":1152,"text":2670},{"id":2778,"depth":1152,"text":2779},{"id":3381,"depth":1152,"text":3382},{"outlineRef":1831,"pairsWith":2656,"status":4401},"new — authored exercises (Multiple Choice + Micro-Parsons + Coding)",{"title":1000,"description":1139},"PKHfkgCB7cJ7iqS45riDuvUFGpc2aGS0eVKc6__jiTc",1792718166177]