1.53k likes | 1.54k Views
Learn how to design and implement objects representing information and physical world objects in Java. Explore the Car class and its properties and behaviors.
E N D
Classes Chapter 4 Spring 2005 CS 101 Aaron Bloomfield
Preparation • Scene so far has been background material and experience • Computing systems and problem solving • Variables • Types • Input and output • Expressions • Assignments • Objects • Standard classes and methods • Decisions (if, switch) • Loops (while, for, do-while) • Now: Experience what Java is really about • Design and implement objects representing information and physical world objects
Object-oriented programming • Basis • Create and manipulate objects with attributes and behaviors that the programmer can specify • Mechanism • Classes • Benefits • An information type is design and implemented once • Reused as needed • No need reanalysis and re-justification of the representation
Known Classes • Classes we’ve seen • BigInteger • String • StringBuffer • Scanner • System • Classes we’ll be seeing soon • BigDecimal
A new example: creating a Car class • What properties does a car have in the real world? • Color • Position (x,y) • Fuel in tank • We will implement these properties in our Car class public class Car { private Color color; private int xpos; private int ypos; private int fuel; //... }
Car - color - xpos - fuel - ypos + … Car’s instance variables public class Car { private Color color; private int xpos; private int ypos; private int fuel; //... }
Car - color = null - xpos = 0 - fuel = 0 - ypos = 0 + … Instance variables and attributes • Default initialization • If the variable is within a method, Java does NOT initialize it • If the variable is within a class, Java initializes it as follows: • Numeric instance variables initialized to 0 • Logical instance variables initialized to false • Object instance variables initialized to null
Car behaviors or methods • What can a car do? And what can you do to a car? • Move it • Change it’s x and y positions • Change it’s color • Fill it up with fuel • For our computer simulation, what else do we want the Car class to do? • Create a new Car • Plot itself on the screen • Each of these behaviors will be written as a method
Creating a new car • To create a new Car, we call: • Car car = new Car(); • Notice this looks like a method • You are calling a special method called a constructor • A constructor is used to create (or construct) an object • It sets the instance variables to initial values • The constructor: public Car() { fuel = 1000; color = Color.BLUE; }
Constructors public Car() { fuel = 1000; color = Color.BLUE; } No return type! EXACT same name as class For now, all constructors are public
Our Car class so far public class Car { private Color color; private int xpos; private int ypos; private int fuel; public Car() { fuel = 1000; color = Color.BLUE; } } public class Car { private Color color = Color.BLUE; private int xpos; private int ypos; private int fuel = 1000; public Car() { } }
Car - color = Color.BLUE - xpos = 0 - fuel = 1000 - ypos = 0 + Car() + … Our Car class so far public class Car { private Color color = Color.BLUE; private int xpos = 0; private int ypos = 0; private int fuel = 1000; public Car() { } } • Called the default constructor • The default constructor has no parameters • If you don’t include one, Java will SOMETIMES put one there automatically
Another constructor • Another constructor: public Car (Color c, int x, int y, int f) { color = c; xpos = x; ypos = y; fuel = f; } • This constructor takes in four parameters • The instance variables in the object are set to those parameters • This is called a specific constructor • An constructor you provide that takes in parameters is called a specific constructor
Car - color = Color.BLUE - xpos = 0 - fuel = 1000 - ypos = 0 + Car() + Car (Color, int, int, int) + … Our Car class so far public class Car { private Color color = Color.BLUE; private int xpos = 0; private int ypos = 0; private int fuel = 1000; public Car() { } public Car (Color c, int x, int y, int f) { color = c; xpos = x; ypos = y; fuel = f; } }
DeCSS: The program #include<stdlib.h> typedef unsigned int uint; char ctb[512]="33733b2663236b763e7e362b6e2e667bd393db0643034b96de9ed60b4e0e4\ 69b57175f82c787cf125a1a528fca8ac21fd999d10049094190d898d001480840913d7d35246\ d2d65743c7c34256c2c6475dd9dd5044d0d4594dc9cd4054c0c449559195180c989c11058185\ 081c888c011d797df0247074f92da9ad20f4a0a429f53135b86c383cb165e1e568bce8ec61bb\ 3f3bba6e3a3ebf6befeb6abeeaee6fb37773f2267276f723a7a322f6a2a627fb9f9b1a0e9a9e\ 1f0b8f8b0a1e8a8e0f15d1d5584cd8dc5145c1c5485cc8cc415bdfdb5a4edade5f4bcfcb4a5e\ cace4f539793120692961703878302168286071b7f7bfa2e7a7eff2bafab2afeaaae2ff"; typedef unsigned char uchar;uint tb0[11]={5,0,1,2,3,4,0,1,2,3,4};uchar* F=NULL; uint lf0,lf1,out;void ReadKey(uchar* key){int i;char hst[3]; hst[2]=0;if(F==\ NULL){F=malloc(256);for(i=0;i<256;i++){hst[0]=ctb[2*i];hst[1]=ctb[2*i+1];F[i]=\ strtol(hst,NULL,16);}}out=0;lf0=(key[1]<<9)|key[0]|0x100;lf1=(key[4]<<16)|(key\ [3]<<8)|key[2];lf1=((lf1&0xfffff8)<<1)|(lf1&0x7)|0x8;}uchar Cipher(int sw1,\ int sw2){int i,a,b,x=0,y=0;for(i=0;i<8;i++){a=((lf0>>2)^(lf0>>16))&1;b=((lf1\ >>12)^(lf1>>20)^(lf1>>21)^(lf1>>24))&1;lf0=(lf0<<1)|a;lf1=(lf1<<1)|b;x=(x>>1)\ |(a<<7);y=(y>>1)|(b<<7);}x^=sw1;y^=sw2;return out=(out>>8)+x+y;} void \ CSSdescramble(uchar *sec,uchar *key){uint i;uchar *end=sec+0x800;uchar KEY[5]; for(i=0;i<5;i++)KEY[i]=key[i]^sec[0x54+i];ReadKey(KEY);sec+=0x80;while(sec!=\ end)*sec++=F[*sec]^Cipher(255,0);}void CSStitlekey1(uchar *key,uchar *im) {uchar k[5];int i; ReadKey(im);for(i=0;i<5;i++)k[i]=Cipher(0,0);for(i=9;i>=0;\ i--)key[tb0[i+1]]=k[tb0[i+1]]^F[key[tb0[i+1]]]^key[tb0[i]];}void CSStitlekey2\ (uchar *key,uchar *im){uchar k[5];int i;ReadKey(im);for(i=0;i<5;i++)k[i]=\ Cipher(0,255);for(i=9;i>=0;i--)key[tb0[i+1]]=k[tb0[i+1]]^F[key[tb0[i+1]]]^key\ [tb0[i]];}void CSSdecrypttitlekey(uchar *tkey,uchar *dkey){int i;uchar im1[6]; uchar im2[6]={0x51,0x67,0x67,0xc5,0xe0,0x00};for(i=0;i<6;i++)im1[i]=dkey[i]; CSStitlekey1(im1,im2);CSStitlekey2(tkey,im1);}
DeCSS: The poem How to decrypt a DVD: in haiku form. (Thanks, Prof. D. S. T.) ------------------------ (I abandon my exclusive rights to make or perform copies of this work, U. S. Code Title Seventeen, section One Hundred and Six.) Muse! When we learned to count, little did we know all the things we could do some day by shuffling those numbers: Pythagoras said "All is number" long before he saw computers and their effects, or what they could do Table Zero is: Five, zero, one, two, three, four, oh, one, two, three, four. Table One is long: two to the eighth power bytes. Ready? Here they are: Fifty one; then one hundred fifteen; fifty nine; thirty eight; ninety nine; thirty five; one hundred seven; one hundred eighteen; sixty two; one hundred twenty six; fifty four; forty three; one hundred ten; then
DeCSS: The number • The world’s first illegal prime number: 485650789657397829309841894694286137707442087351357924019652073668698513401047237446968797439926117510973777701027447528049058831384037549709987909653955227011712157025974666993240226834596619606034851742497735846851885567457025712547499964821941846557100841190862597169479707991520048667099759235960613207259737979936188606316914473588300245336972781813914797955513399949394882899846917836100182597890103160196183503434489568705384520853804584241565482488933380474758711283395989685223254460840897111977127694120795862440547161321005006459820176961771809478113622002723448272249323259547234688002927776497906148129840428345720146348968547169082354737835661972186224969431622716663939055430241564732924855248991225739466548627140482117138124388217717602984125524464744505583462814488335631902725319590439283873764073916891257924055015620889787163375999107887084908159097548019285768451988596305323823490558092032999603234471140776019847163531161713078576084862236370283570104961259568184678596533310077017991614674472549272833486916000647585917462781212690073518309241530106302893295665843662000800476778967984382090797619859493646309380586336721469695975027968771205724996666980561453382074120315933770309949152746918356593762102220068126798273445760938020304479122774980917955938387121000588766689258448700470772552497060444652127130404321182610103591186476662963858495087448497373476861420880529443
DeCSS: The recordings • All this info from http://www-2.cs.cmu.edu/~dst/DeCSS/Gallery/ • Or do a Google search for “decss gallery”
c1 c2 Car Car - color = Color.BLUE - color = Color.BLACK - xpos = 0 - xpos = 1 - fuel = 1000 - fuel = 500 - ypos = 0 - ypos = 2 + Car() + Car (Color, int, int, int) + … + Car() + Car (Color, int, int, int) + … Using our Car class • Now we can use both our constructors: Car c1 = new Car(); Car c2 = new Car (Color.BLACK, 1, 2, 500);
So what does private mean? Note that it’s a different class! • Consider the following code public class CarSimulation { public static void main (String[] args) { Car c = new Car(); System.out.println (c.fuel); } } • Recall that fuel is a private instance variable in the Car class • Private means that code outside the class CANNOT access the variable • For either reading or writing • Java will not compile the above code • If fuel were public, the above code would work
So how do we get the fuel of a Car? • Via accessor methods in the Car class: public int getFuel() { return fuel; } public Color getColor() { return color; } • As these methods are within the Car class, they can read the private instance variables • As the methods are public, anybody can call them • public int getYPos() { • return ypos; • } • public int getXPos() { • return xpos; • }
So how do we set the fuel of a Car? • Via mutator methods in the Car class: public void setFuel (int f) { fuel = f; } public void setColor (Color c) { color = c; } • As these methods are within the Car class, they can read the private instance variables • As the methods are public, anybody can call them public void setXPos (int x) { xpos = x; } public void setYPos (int y) { ypos = y; }
Car - color = Color.BLUE - xpos = 0 - fuel = 1000 - ypos = 0 + Car() + Car (Color, int, int, int) +void setXPos (int x) +void setYPos (int y) +void setPos (int x, int y) +void setColor (Color c) +void setFuel (int f) +int getFuel() +int getXPos() +int getYPos() +Color getColor() + … Why use all this? • These methods are called a get/set pair • Used with private variables • We’ll see why one uses these later in this slide set • Our Car so far:
A solution to commenting your code • The commentator: http://www.cenqua.com/commentator/
Back to our specific constructor public class Car { private Color color = Color.BLUE; private int xpos = 0; private int ypos = 0; private int fuel = 1000; public Car (Color c, int x, int y, int f) { color = c; xpos = x; ypos = y; fuel = f; } } public class Car { private Color color = Color.BLUE; private int xpos = 0; private int ypos = 0; private int fuel = 1000; public Car (Color c, int x, int y, int f) { setColor (c); setXPos (x); setYPos (y); setFuel (f); } }
Back to our specific constructor • Using the mutator methods (i.e. the ‘set’ methods) is the preferred way to modify instance variables in a constructor • We’ll see why later
So what’s left to add to our Car class? • What else we should add: • A mutator that sets both the x and y positions at the same time • A means to “use” the Car’s fuel • A method to paint itself on the screen • Let’s do the first: public void setPos (int x, int y) { setXPos (x); setYPos (y); } • Notice that it calls the mutator methods
Using the Car’s fuel • Whenever the Car moves, it should burn some of the fuel • For each pixel it moves, it uses one unit of fuel • We could make this more realistic, but this is simpler public void setXPos (int x) { xpos = x; } public void setYPos (int y) { ypos = y; } public void setXPos (int x) { fuel -= Math.abs (getXPos()-x); xpos = x; } public void setYPos (int y) { fuel -= Math.abs (getYPos()-y); ypos = y; }
Using the Car’s fuel public void setPos (int x, int y) { setXPos(x); setYPos(y); } • Notice that to access the instance variables, the accessor methods are used • Math.abs() gets the absolute value of the passed parameter public void setPos (int x, int y) { setXPos(x); setYPos(y); }
Drawing the Car • The simple way to have the Car draw itself: public void paint (Graphics g) { g.setColor (color); g.fillRect (xpos-50, ypos-100, 100, 200); } • This draws a single rectangle that is 100 by 200 pixels in size • Lets use constants for the car’s height and width...
Drawing the Car • A better version: private final int CAR_WIDTH = 100; private final int CAR_HEIGHT = 200; public void paint (Graphics g) { g.setColor (color); g.fillRect (getXPos()-CAR_WIDTH/2, getYPos()-CAR_HEIGHT/2, CAR_WIDTH, CAR_HEIGHT); } • This makes it easier to change the car size • We could have made the car size instance variables and set them via mutators • Lets add tires!
Drawing the Car private final int CAR_WIDTH = 100; private final int CAR_HEIGHT = 200; private final int TIRE_WIDTH = 20; private final int TIRE_HEIGHT = 40; private final int TIRE_OFFSET = 20; public void paint (Graphics g) { g.setColor (color); g.fillRect (getXPos()-CAR_WIDTH/2, getYPos()-CAR_HEIGHT/2, CAR_WIDTH, CAR_HEIGHT); // Draw the tires g.setColor (Color.BLACK); g.fillRect (getXPos()-(CAR_WIDTH/2+TIRE_WIDTH), getYPos()-(CAR_HEIGHT/2-TIRE_OFFSET), TIRE_WIDTH, TIRE_HEIGHT); g.fillRect (getXPos()-(CAR_WIDTH/2+TIRE_WIDTH), getYPos()+(CAR_HEIGHT/2-TIRE_OFFSET-TIRE_HEIGHT), TIRE_WIDTH, TIRE_HEIGHT); g.fillRect (getXPos()+(CAR_WIDTH/2), getYPos()+(CAR_HEIGHT/2-TIRE_OFFSET-TIRE_HEIGHT), TIRE_WIDTH, TIRE_HEIGHT); g.fillRect (getXPos()+(CAR_WIDTH/2), getYPos()-(CAR_HEIGHT/2-TIRE_OFFSET), TIRE_WIDTH, TIRE_HEIGHT); } Don’t worry about this – just know that it draws four tires
What happens when the car runs out of fuel? • We could do a number of things: • Not allow the car to move anymore • Print out a message saying, “fill me up!” • We’ll color the car red • We’ll insert the following code at the beginning of the paint() method: if ( fuel < 0 ) { color = Color.RED; }
Drawing the Car private final int CAR_WIDTH = 100; private final int CAR_HEIGHT = 200; private final int TIRE_WIDTH = 20; private final int TIRE_HEIGHT = 40; private final int TIRE_OFFSET = 20; public void paint (Graphics g) { if ( fuel < 0 ) { color = Color.RED; } g.setColor (color); g.fillRect (getXPos()-CAR_WIDTH/2, getYPos()-CAR_HEIGHT/2, CAR_WIDTH, CAR_HEIGHT); // Draw the tires g.setColor (Color.BLACK); g.fillRect (getXPos()-(CAR_WIDTH/2+TIRE_WIDTH), getYPos()-(CAR_HEIGHT/2-TIRE_OFFSET), TIRE_WIDTH, TIRE_HEIGHT); g.fillRect (getXPos()-(CAR_WIDTH/2+TIRE_WIDTH), getYPos()+(CAR_HEIGHT/2-TIRE_OFFSET-TIRE_HEIGHT), TIRE_WIDTH, TIRE_HEIGHT); g.fillRect (getXPos()+(CAR_WIDTH/2), getYPos()+(CAR_HEIGHT/2-TIRE_OFFSET-TIRE_HEIGHT), TIRE_WIDTH, TIRE_HEIGHT); g.fillRect (getXPos()+(CAR_WIDTH/2), getYPos()-(CAR_HEIGHT/2-TIRE_OFFSET), TIRE_WIDTH, TIRE_HEIGHT); }
Our car in action • CarGUI.java
What I’m not expecting you to know yet… • What the static keyword means • And why the main() method is • And why other methods are not • Why you should always call the mutator methods, instead of setting the field directly • Just know that it’s a good programming practice, and follow it • We’ll see why later • Why instance variables are supposed to be private • Just know that it’s a good programming practice, and follow it • Again, we’ll see why soon
Terminology • An attribute of a class can be called: • Instance or class variable (we’ll see the difference later) • Static variable (or static field) • Synonymous with class variable • Field • Generally means either type • Variable • Also means either type • Attribute • Property • Argh! • I will generally use the terms variable or field when I am not differentiating between the two • And instance variable and class variable when I am
The main() method • Consider a class with many methods: public class WhereToStart { public static void foo (int x) { // ... } public static void bar () { // ... } public static void main (String[] args) { // ... } } • Where does Java start executing the program? • Always at the beginning of the main() method!
Running a class without a main() method • Consider the Car class • It had no main() method! • The main() method was in the CarSimulation (or CarGUI) class • So let’s try running it…
Program Demo • Car.java
Variable scoping • A variable is visible within the block it is declared in • Called the “scope” of the variable public class Scoping { int z public static void foo (int x) { // ... } public static void bar () { // ... } public static void main (String[] args) { int y; // ... } } This instance variable is visible anywhere in the Scoping class This parameter is visible only in the foo() method This local variable is visible until the end of the main() method
Variable initialization • A local variable is NOT initialized to a default value • This is any variable declared within a method • Or within a block within a method • This is pretty stupid, in my opinion • Parameters are initialized to whatever value they are passed • Instance and class variables are initialized to default values • Numbers to zero, booleans to false, references to null • This means any field in a class • Either class variables or instance variables