Today Sarah wrote to me a brief summary of what she wanted to develop. I use her example (below) just because it's brief and came last. It also has an almost perfect combination of problems and seems to strike the perfect compromise between vague enough to leave room for interpretation and inspiration, and too vague to nail down any of the implementation and user interface details that we'd need to work out next. So here's Sarah's short list of program ideas: +----------------------------------------------------------- | 1. bakery | choose what to bake, amt of ingrediants, and cook time. decide if it cooks right or not | 2. Directions | database 10 different ways, A -> B | 3. Base 10 converter | Convert Base 10 to Binary +----------------------------------------------------------- So we start with some important remarks based on this ideal example: a) in each of these problems we need a short but clear example of what that means. A typical case study. Something that will shed some light on how the program will work without saying anything about Java, or how that will work in Java. I am not sure what a good example might be in the case of (1), I am not sure what (2) means just yet, it may mean so many things, but I have an example in the case of (3). b) we have clearly state what the user sees, when the user interacts with the program. I am not clear at all now what the interface looks at (1) but I have Google-biased idea of what the program at (2) might look like. As far as (3) is concerned I can't think of anything but a text-based, command line interface (lazy?). c) prototype, and we discuss what from Java is useful here (that's based on today's material and tomorrow's notes). For (a) 5 --> 101 12 --> 1100 1 0 2 0 4 1 8 1 16 0 List powers of 2 smaller than the number and then work out a puzzle. It looks like we could express our reasoning like this: Start with the highest power of 2 smaller than the number. Take it out of the number and write a 1, or 0 if you can't. Go to the next power of 2, the next smaller power of 2 and do the same. When you're out of number (number is zero) you finished. 9 8 print a 1 and number becomes 9-8 === 1 1 4 print a 0 and number becomes 1 1 2 print a 0 and number stays 1 1 1 print a 1 because I can take this power of 2 out of the number which becomes 1-1 == 0 0 hey wait a minute I need to stop because I have exhausted my number! So I printed 1001 and that's 9 in base 2. Next let's go back to Java. Writing programs in Java is like playing hockey. Learning Java is like learning to skate so you can play hockey. And now we're looking at our skates, etc. Yesterday we said: Java programs are made out of classes. Classes are containers (of variables and/or methods). Variables and methods placed/defined/located in a class are called: class members. Exercise: define a class with an class variable and a class method in it. Compile. Class members need to be marked as static. class One { static int n; public static void main(String[] args) { System.out.println( n ); // 0, it's One.n // you're advised against this shortcut for now System.out.println( One.n ); // prints 0 System.out.println( Two.n ); // 0 Two.n = 3; One.n = 5; System.out.println( One.n ); // prints 5 System.out.println( Two.n ); // 3 System.out.println(One.n + Two.n); // 8 } } class Two { static int n; } What does the absence of static going to do for me? So we try this: class One { static int n; public static void main(String[] args) { System.out.println( Two.n ); Two.n = 5; System.out.println( Two.n ); } } class Two { /*static*/ int n; } Does it compile? No. Why? Because the variable n is non-static. A non-static variable is also called an instance variable. We developed this example: class One { static int n; public static void main(String[] args) { Car a; a = new Car(); System.out.println( a.n ); a.n = 4; System.out.println( a.n ); Car b; b = new Car(); System.out.println( b.n ); b.n = 12; System.out.println( b.n ); } } class Car { int n; // this is ghost of a building // blueprint for a building named n // non-static members together form the // blueprint of objects that can be created // from this class (that this class stands // for). One blueprint per class. Contains // all the non-static members in it. If you // instantiate it you get an object (container // of methods and variables). An object is an // instance of the blueprint. It contains // actual (instance) members as listed in the // blueprint. Class: island, factory. Class // members: static members located on the // island or in the factory. Blueprint: the // things we make on the island/in that // factory. Blueprint is vision, ghost, like // the 2014 Tesla. Once the factory starts // producing those we end up with instances // of this blueprint: lots of identical cars. } This is where the lecture ended. We will start the lab trying to model something with objects (given what we know). URLs we might visit: http://www.cs.indiana.edu/classes/a201-dger/spr2005/diagrams.ppt http://www.cs.indiana.edu/classes/a201-dger/spr2005/spiff21.ppt http://www.cs.indiana.edu/classes/a201-dger/sum2002/notes/rodS.html Plan for the rest of the lab: a) methods (syntax, static or non-static) b) constructors c) let's model a Car (VINs, factory keeps track) d) what's the difference between: and +---------------------------------------------+------------------------------------------------+ | class One { | class One { | | Car a = new Car(); | | | public static void main(String[] args) { | public static void main(String[] args) { | | | Car a = new Car(); | | } | } | | } | } | +---------------------------------------------+------------------------------------------------+ +------------------------------------------------- | How does this relate to the two examples above: | | class One { | static Car a; | public static void main(String[] args) { | One.a = new Car(); | } | } | +-------------------------------------------------- e) model some more, answer questions, etc. First we model a Clock: class One { public static void main(String[] args) { Clock c1, c2, c3; c1 = new Clock(); c1.h = 17; c1.m = 53; c1.s = 36; c2 = new Clock(); // c2.h, c2.m, c2.s are all 0 c3 = new Clock(); // same for c3 } } class Clock { int h; int m; int s; } Now let's see how we can use BlueJ to explore these concepts. Go to: http://www.bluej.org/ to download BlueJ. Click on Download and then choose the third entry: all other systems (executable jar file) (4.8 Mb) bluej-251.jar Click on it and select: Open with Java. A window pops up and choose the Desktop as the directory to install in. Select the JDK directory (browse to it, it's c:\program files\java\jdk1.6.0_07) and click Install. Click Done when finished. BlueJ was installed in a folder bluej on the Desktop. I went into this folder and started (double-clicked on) the bluej file. A terminal window pops up, followed by the BlueJ IDE. Choose Project, Create New, navigate to the Desktop and create 0715. Create a new class, name it Clock. Right on it, you can compile it (no point to, now) edit (not yet) or remove (yes!). If you edit it you see a lot of code. Look at it a little then delete it. Type this: class Clock { int h; int m; int s; } Save, compile, then right click and create a new Clock() (give it a name, yeah) then another one and another one. In BlueJ we don't need One with the main as before. We are the main, we run it ourselves. So we inspect, use the codepad to change, inspect some more, remove etc. Now we want to add a method. What does a method have: a) name (main) b) a body (list of instructions, steps to be taken when called, inside the method) curly braces are types around the body c) parameters (if any: ingredients) params are listed separated by commas inside a pair of round parens d) they can be static or non-static this means they're in the class or in the blueprint e) they can be public or not let's just ignore that for the moment f) a return type void is a return type In Java there are two basic types: a) primitive types (int, double, boolean, char) b) user-defined types (blueprints in classes or objects) class Clock { int h; int m; int s; void fun(int one, int two) { m = two; s = one; } } This example is contrived but simple and illuminating. We then created this meaningful model: class Clock { int h; int m; int s; void set(int hour, int minute, int seconds) { h = hour; m = minute; s = seconds; } String report() { return "(" + h + ":" + m + ":" + s + ")"; } void tick() { s += 1; if (s == 60) { s = 0; m += 1; if (m == 60) { m = 0; h += 1; if (h == 24) { h = 0; } } } System.out.println(report()); } } After class Mohammed and Gang stayed some more and we discussed the following examples: A Car includes Tires and an Engine. But a Car does not have to include the definition of Tire, Engine. But it can include it. Although it doesn't have to. Below we have: composition. So in file Car.java (maintained by gghuang): class Car { Tire a, b, c, d; // these variables are null before initialization Engine e; Car() { } // the default no arg constructor leaves them null /* Car() { e = new Engine(); a = new Tire(); b = new Tire(); c = new Tire(); d = new Tire(); } */ Car(Engine e, Tire t1, Tire t2, Tire t3, Tire t4) { this.e = e; // ... and the rest } } While in class Tire.java (maintained by dgerman): class Tire { } While in class Engine.java (maintained by mohmoham): class Engine { } // ---------------------------------------------------- Another way would be to build the car through inheritance. No. 1 -- we don't know that yet. No. 2 -- we need a good reason for that. I can do it below, but it will look very weird in this case: class Tire { } class Engine extends Tire { // add the engine features here } class Car extends Engine { // add stuff about Car } In the first case Car a = new Car() how do you access the tire? Probably a.a In the second case if Car a = new Car() how do you access the tire? You ARE the tire. So here's some more examples of this: class Point { Point(int a, int b) { x = a; y = b; } int x, y; void moveTo(int targetX, int targetY) { x = targetX; y = targetY; } } Now we can define a Line by composition: class Line { Point a, b; Line(Point one, Point two) { a = one; b = two; } } We can also create a Vector by inheritance: class Vector extends Point { Point destination; Vector(int x, int y, Point d) { super(x, y); destination = d; } } Is this better or how is it exactly? Note a Line can't move but we can move its endpoints. A Vector can move: the source that it is moves, in fact. You can also move its destination (which can be shared). Two Vectors can't share the source, but they can have sources with identical values. Lines can share endpoints with no problems. Inheritance is beneficial when you need to inherit behaviour not as much as structure/data. We played with these definitions, then wrote another one: class Car { static int number; // global to all instances created from this class int vin; double tank; // global to add and drive Car() { Car.number += 1; this.vin = Car.number; } void add(int fuel) { this.tank += fuel; } void drive(int miles) { this.tank -= miles / 55.0; // System.out.println(Math.E); } static void paint(Car a) { int n = -200; a.vin = n; // it makes no sense to say vin = -200; // or it makes no sense to saqy this.vin = -200; } } Levels of globalness: -- a static variable is global to all instances (objects) -- an instance (object) variable is global to all instance (object) methods Scope, lifespan etc. class Triangle { static int flower; Point a, b, c; } Creating a Triangle initializes the instance variables to null. The static variable flower is initialized to 0 (zero). These are things we will cover tomorrow.