Java by Example - introducing classes and objects
You will heard the buzzword OOP, or "Object Oriented Programming" before, but maybe you don't know exactly what it means yet. The following examples are supposed to shed some light onto that mystery. Have a look at the following, not object oriented example applet. Click somewhere inside the applet to paint a bubble with random diameter and color. The bubble is defined inside the main class and is totally dependent from every modification you might do to the main class code.
//Sourcecode
import java.awt.*;
import java.applet.*;
//bubbles applet without bubble class
public class Project22 extends Applet
{
Image Buffer;
Graphics gBuffer;
public void init()
{
Buffer=createImage(size().width,size().height);
gBuffer=Buffer.getGraphics();
}
public boolean mouseDown(Event evt,int x,int y)
{
drawRandomBubble(x,y);
repaint();
return true;
}
public void drawRandomBubble(int x, int y)
{
int red=(int)(Math.random()*255);
int green=(int)(Math.random()*255);
int blue=(int)(Math.random()*255);
Color randomColor=new Color(red, green, blue);
gBuffer.setColor(randomColor);
//generate a random number between 10 and 100
int diameter=(int)(Math.random()*90)+10;
//make mouse cursor the center of our random bubble
gBuffer.fillOval(x-diameter/2,y-diameter/2,diameter,diameter);
}
public void update(Graphics g)
{
paint(g);
}
public void paint(Graphics g)
{
gBuffer.setColor(Color.black);
gBuffer.drawString("Click the applet to paint bubbles!", 50,20);
g.drawImage (Buffer,0,0, this);
}
}
|
This next applet uses a separate "Bubble" class (which is also a separate *.class file after compilation). This class is a kind of "black box" for the rest of the program. It has it's own variables and methods. To use a class, the program must create an instance, or "object" of that class: Bubble myBubble; and myBubble = new Bubble(x,y);. The first declared a variable name for our object, the second created the object itself. The arguments (x,y) are the arguments of the constructor. The constructor is a method that is called from the creating class in the moment an object is created. You can pass arguments from the creating class to the object here, or make any initializations for the new class. A class can have several constructor methods, that are distinguished by the type and number of arguments. Via that object (you can create as much as you need), the program can call methods of that class. Use the "." operator between object name and method name to access methods of a class, like this: myBubble.paint(gBuffer). You can also access variables of the objects directly: myBubble.x - but that is not recommended, to avoid accidentally changing data in your object. You would also have to declare them public to allow access from outside the class. Try to use only methods, to access variables of an object and make your variables private (only accessable from within the class, set by default). Instead of calling
OtherClass.a=10; you can define a public method in that class:
public void setA(int a)
{
this.a=a;
}
this.a means: a reference to this instance, to this object of a class. You could also write, for instance:
public void setA(int varA)
{
a=varA;
}
This way you are able to change data of an object indirectly, without dealing with the data itself. To get the value of a variable indirectly, you can use another method:
public int getA()
{
return a;
}
, instead of calling: a=OtherClass.a;, a being a public int of the other class. In simple programs it is not neccessary to do this, but in big programs with many classes
it provides for more safety and avoids bugs, by implementing the paradigma of encapsulation, which means - classes only interact with predefined interfaces (or methods) and are not allowed to change each others data directly.
//Sourcecode
import java.awt.*;
import java.applet.*;
//bubbles applet with a separate bubble class!
class Bubble
{
//instance variables
int x, y;
Graphics g;
//constructor
public Bubble(int x, int y)
{
this.x=x;
this.y=y;
}
public void drawRandomBubble(int x, int y)
{
int red=(int)(Math.random()*255);
int green=(int)(Math.random()*255);
int blue=(int)(Math.random()*255);
Color randomColor=new Color(red, green, blue);
g.setColor(randomColor);
//generate a random number between 10 and 100
int diameter=(int)(Math.random()*90)+10;
//make mouse cursor the center of our random bubble
g.fillOval(x-diameter/2,y-diameter/2,diameter,diameter);
}
public void paint(Graphics gr)
{
g=gr;
drawRandomBubble(x, y);
}
}
public class Project23 extends Applet
{
Image Buffer;
Graphics gBuffer;
Bubble myBubble;
public void init()
{
Buffer=createImage(size().width,size().height);
gBuffer=Buffer.getGraphics();
}
public boolean mouseDown(Event evt,int x,int y)
{
myBubble = new Bubble(x,y);
myBubble.paint(gBuffer);
repaint();
return true;
}
public void update(Graphics g)
{
paint(g);
}
public void paint(Graphics g)
{
gBuffer.setColor(Color.black);
gBuffer.drawString("Click the applet to paint classy bubbles!", 30,20);
g.drawImage (Buffer,0,0, this);
}
}
|
You might wonder why you should need a separate class at all for the last program we discussed, but the advantages might come clearer to you in a more complicated one. The next applet uses a thread to make the bubbles you produce by clicking grow. The applet calles the grow() method of the GrowingBubbles class from within the run() method, which does all there is to do to make the
bubbles grow: increment its diameter. Making the objects of your programs also objects of a separate class, allows for more logical and simple programming, especially for big projects, as you will soon discover.
//Sourcecode
import java.awt.*;
import java.applet.*;
class GrowingBubble
{
//instance variables
int x, y, diameter, startDiameter, endDiameter;
Color randomColor;
Graphics g;
//constructor
public GrowingBubble()
{
int red=(int)(Math.random()*255);
int green=(int)(Math.random()*255);
int blue=(int)(Math.random()*255);
//each bubble object has one random color
randomColor=new Color(red, green, blue);
//start diameter between 10 and 30
startDiameter=(int)(Math.random()*20)+10;
//end diameter between 50 and 150
endDiameter=(int)(Math.random()*100)+50;
diameter=startDiameter;
}
public void setPosition(int x, int y)
{
this.x=x;
this.y=y;
}
public void drawBubble()
{
g.setColor(randomColor);
g.fillOval(x-diameter/2,y-diameter/2,diameter,diameter);
}
public void grow()
{
//quickly grow, till end diameter is reached
if(diameter<endDiameter)
diameter+=4;
}
public void paint(Graphics gr)
{
g=gr;
drawBubble();
}
}
public class Project24 extends Applet implements Runnable
{
Image Buffer;
Graphics gBuffer;
GrowingBubble myBubble;
Thread runner;
boolean clicked;
public void init()
{
Buffer=createImage(size().width,size().height);
gBuffer=Buffer.getGraphics();
}
public void start()
{
if (runner == null)
{
runner = new Thread (this);
runner.start();
}
}
public void stop()
{
if (runner != null)
{
runner.stop();
runner = null;
}
}
public void run()
{
while(true)
{
//halt the thread for 15 ms here
try {runner.sleep(15);}
catch (Exception e) { }
//bubble methods may only be accessed, if we have
//created the object in the mouseDown method!
if(clicked)
{
myBubble.grow();
myBubble.paint(gBuffer);
}
repaint();
}
}
public boolean mouseDown(Event evt,int x,int y)
{
myBubble = new GrowingBubble();
myBubble.setPosition(x,y);
clicked=true;
return true;
}
public void update(Graphics g)
{
paint(g);
}
public void paint(Graphics g)
{
gBuffer.setColor(Color.black);
gBuffer.drawString("Click the applet to paint growing bubbles!", 30,20);
g.drawImage (Buffer,0,0, this);
}
}
|
The bubbles you produce here don't just grow, they breathe! To achieve this, we need more than one object of our BreathingBubbles class, to make every one of them really independent from the others. To achieve this, we create an array of 100 bubble objects. With each mouseclick, a new one is created and initialized with the mouse coordinates. The object is responsible for it's own color, minimum diameter and maximum diameter.
//Sourcecode
import java.awt.*;
import java.applet.*;
class BreathingBubble
{
//instance variables
int x, y, diameter, startDiameter, endDiameter;
boolean growing=true;
Color randomColor;
Graphics g;
//constructor
public BreathingBubble()
{
int red=(int)(Math.random()*255);
int green=(int)(Math.random()*255);
int blue=(int)(Math.random()*255);
//each bubble object has one random color
randomColor=new Color(red, green, blue);
//start diameter between 10 and 30
startDiameter=(int)(Math.random()*20)+10;
//end diameter between 50 and 150
endDiameter=(int)(Math.random()*100)+50;
diameter=startDiameter;
}
public void setPosition(int x, int y)
{
this.x=x;
this.y=y;
}
public void drawBubble()
{
g.setColor(randomColor);
g.fillOval(x-diameter/2,y-diameter/2,diameter,diameter);
}
public void breathe()
{
//grow till end diameter is reached
if(growing)
{
if(diameter<endDiameter)
diameter++;
else
growing=false;
}
//shrink till start diameter is reached
else
{
if(diameter>startDiameter)
diameter--;
else
growing=true;
}
}
public void paint(Graphics gr)
{
g=gr;
drawBubble();
}
}
public class Project25 extends Applet implements Runnable
{
Image Buffer;
Graphics gBuffer;
BreathingBubble myBubble[];
Thread runner;
boolean clicked;
int index;
int MAX=100;
public void init()
{
Buffer=createImage(size().width,size().height);
gBuffer=Buffer.getGraphics();
myBubble = new BreathingBubble[MAX];
}
public void start()
{
if (runner == null)
{
runner = new Thread (this);
runner.start();
}
}
public void stop()
{
if (runner != null)
{
runner.stop();
runner = null;
}
}
public void run()
{
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
while(true)
{
try {runner.sleep(15);}
catch (Exception e) { }
//bubble methods may only be accessed, if we have
//created the object in the mouseDown method!
if(clicked)
{
for(int i=0;i<index;i++)
{
myBubble[i].breathe();
myBubble[i].paint(gBuffer);
}
}
repaint();
}
}
public boolean mouseDown(Event evt,int x,int y)
{
if(index<MAX)
{
myBubble[index] = new BreathingBubble();
myBubble[index].setPosition(x,y);
index++;
}
clicked=true;
return true;
}
public void update(Graphics g)
{
paint(g);
}
public void paint(Graphics g)
{
gBuffer.setColor(Color.black);
gBuffer.drawString("Click the applet to paint breathing bubbles!", 20,20);
g.drawImage (Buffer,0,0, this);
//paint the background white (must be done last!)
gBuffer.setColor(Color.white);
gBuffer.fillRect(0,0,size().width,size().height);
}
}
|
|