Instance vs. Class
Up to this point we have created a few
classes and I have been trying to avoid saying this word until now. Yes
instance, what it means and the what difference between instance and class is. I
referred to creating objects of a class up until now and that is what instance
means. When you create an object you are creating an instance of a class.
Now how does that differ from Class? Well
instance members are based on that current object and class members don't rely
on anything and usually take in parameters for the necessary data. Class methods
are not as common as instance methods and are usually some type of utility. You
would access an instance method through a variable that holds an object
(instance) of the class. The class methods do not need an object or even a
variable and be accessed by the class name (i.e. ClassName.methodName()). Instance
methods are based on the object so they differ depending on the object where
there is only one class method so the value wouldn't change unless there are
parameters. This does not mean you can only have one class sub/function. This is
where it may start to get confusing. One way to show this is using the wrapper
classes in Java.
The main wrapper classes in Java are those
that wrap the primitive data types. For example: Integer wraps int, Character wraps
char, Double wraps double and so on. Each primitive type has a wrapper and
Character). The reason behind the wrapper classes is to give object
functionality when needed but still be able to hold primitive data.
We will start by creating a new executable
class called InstancevsClass.
public class InstancevsClass
{
public static void main(String args[])
{
}
}
We will examine some of the instance and class
methods that you may see a lot of. Lets start with String, char and
Character as our first example. A String is kind of like an array of characters
and you can access those individual characters through the charAt(int) instance method.
public static void main(String args[])
{
String str1 = "12345";
String str2 = "abcde";
System.out.println("str1.charAt(2) = " + str1.charAt(2));
System.out.println("str2.charAt(2) = " + str2.charAt(2));
}
Notice that the charAt returns "3" for str1 and
"c" for str2 (charAt is zero based). As I mentioned charAt is an
instance method so therefore it depends on the instance (object). Since str1 and
str2 refer to different String objects using their methods the same way returns
different results.
Now for an instance example using Character. We will
examine a String to determine the types of characters contained within the
String (i.e. numeric, alphabetic, etc). We will examine the string
"a1b2c3d4 e5". Running through each character determining if the
character is numeric, alphabetic or otherwise. Now the easiest way to determine
this is to use Class members of Character: isLetter and isDigit. As mentioned
Class members do not need and are not part of an instance. Therefore they take
their necessary information as arguments. Both isLetter and isDigit both accept
char and use that to compare whether it is a letter or digit.
public static void main(String args[])
{
String compare = "a1b2c3d4 e5";
for (int i = 0; i < compare.length(); i++)
{
char c = compare.charAt(i);
if (Character.isLetter(c))
System.out.println(c + " is a letter.");
else if (Character.isDigit(c))
System.out.println(c + " is a digit.");
else
System.out.println(c + " is neither a letter nor a digit.");
}
}
Another useful thing about Class members is Constants.
Constants give meaning to a value that otherwise wouldn't make sense. The
Integer wrapper class has MAX_VALUE and MIN_VALUE which tells the you lowest and
highest number an Integer or int variable can hold. This would be useful if
trying to cast a long to an int.
long l = 3939498308l;
int i;
if (l < Integer.MIN_VALUE)
i = Integer.MIN_VALUE;
else if (l > Integer.MAX_VALUE)
i = Integer.MAX_VALUE;
else
i = (int)l;
/*
Makes more sense than:
if (l < 2147483647)
i = 2147483647;
else if (l > 2147483647)
i = 2147483647;
else
i = (int)l;
*/
Now you are probably wanting an example of how to create and use your own
class members. Well lets begin. I will use a new rectangle class called
Rectangle2, shown below:
public class Rectangle2
{
private double length;
private double width;
public Rectangle2(double length, double width)
{
this.length = 1;
this.width = 1;
setHeight(length);
setWidth(width);
}
public double getHeight()
{
return length;
}
public void setHeight(double length)
{
if (length > 0)
this.length = length;
}
public double getWidth()
{
return width;
}
public void setWidth(double width)
{
if (width > 0)
this.width = width;
}
public int getNumOfSides()
{
return 2;
}
public double area()
{
return length * width;
}
}
You will notice I used this for the first time. Now
that we are looking at difference between Instance and Class it is easier to
explain what this means. In inheritance we used parent to refer to
the base class. Well this refers to the current instance of a class.
Since the parameters have the same name (length and width) as the class members referring
to them refers to the procedural level variables (parameter length and width).
They do not override each other. They are still separate variables. So to get
around this you can use this to refer to the class level instance members
length and width.
Looking this class over you may instantly see a good use for the
class member. Q: How many sides does a rectangle have? A: 4. Q: Do all rectangles
have four sides? A: Yes. There for getNumOfSides could be a class member since all
Rectangle2 instances would return a value of 4 and therefore there only needs to
be one occurrence of this property. Can you think of anything else? What about
Area? What if you had a length and width and wanted to know the area without creating a
Rectangle2 object?
The usefulness of class members will hopefully start to become apparent as
well as how they work and how they differ from instance members.
We'll begin with the getNumOfSides method. This is where a
decision is needed. You can either make the method a class method or change it
into a Class member constant. Either will work but a constant makes more sense.
To make a member a class member we use the static keyword (mentioned in
the Introduction to Classes lesson).
public static final double NUMBER_OF_SIDES = 4;
// or
public static int getNumOfSides()
{
return 2;
}
That was easy :). The Area, however, is going to be different. We
still want the instance Area so we will add another Area. Now we are getting to the main difference between Class and Instance.
Our current Area is an instance method and is based on the
object's values. A class method does not have those values and therefore it must
receive those values via arguments. Area will need to be supplied a length and
width.
public static double area(double l, double w)
{
return l * w;
}
Notice that these are overloaded functions since they have the same name but
different parameter list. You may also notice something else, the code for the
two areas are very similar.
Since the instance Area function can access the class method Area why not use
it and save us from repeating the calculation.
public double area()
{
return area(length, width);
}
This, however, does not work the other way around. A class
member cannot
access an instance member. Since an instance member will differ depending on the
object the class member wouldn't know which one it is accessing and therefore this
action is not allowed. Because of that class members take in their values
through arguments. If a class member needs to access an instance then it must
take it in as an arguments.
A quick example::
public static void main(String args[])
{
Rectangle2 r = new Rectangle2(3, 2);
System.out.println("The area of r is " + r.area());
System.out.println("The area of a 5 by 4 rectangle is " +
Rectangle2.area(5, 4));
}
Congratulations, you have now finished the Instance vs. Class
lesson. Keep checking in periodically for any changes or additions to this
tutorial.
Author Information:
Adam Schentag
http://www.programmers-corner.com
adam@programmers-corner.com
Comments: