Chapter 10
Doing More With Classes
Overloading Methods
It’s common to have multiple methods (or constructors) with the same name but different parameters. These are called overloaded methods (or constructors).For example, in our Book class, we might want to overload the constructor so we have a version that accepts arguments. We’d write:
//constructor from earlier
public Book()
{
title = "Untitled Book"; //set the title of the book. etc
numpages = 0;
isHardcover = true;
}
//overloaded "parameterized" constructor
public Book(String t, int n, boolean h)
{
title = t;
numpages = n;
isHardcover = h;
}
How does the compiler know which version of an overloaded method/constructor to use? It all depends on what arguments are provided by the calling method. For example, given:
Book book1 = new Book();
Book book2 = new Book(“My Life”, 125, true);
Book book3 = new Book(35); //will cause an error
The first line would invoke the first constructor, the second would invoke the second, and the third would not compile (would cause an error), because there is no version of the constructor that accepts a single int as a parameter.
Note that no two overloaded methods can not have the same numer and type of variables in the same order. For example, public void myMethod(int numCats, int numDogs) and public void myMethod(int numDogs, int numCats) will not work, because given myMethod(4,6), the compiler would have no way of knowing which version of the method should apply (it only knows there is int, int, so there can only be one version of the method to match).
We might also overload the private printStars method, like so
private void printStars(){
System.out.println("**************************");
}
//overloaded with a parameter for how many stars to print
private void printStars(int number){
for (int x = 0; x < number; x++){
System.out.print("*"); //print single * and stay on line
System.out.println();
}
}
Now if we were to write printStars(), we'll get the number of stars in the original method (there are 26), but if we were to write printStars(20), we would get a line of 20 stars.
Static
Static variables and methods are created once for the class. They are not specific to individual instances (objects) of the class. Because of this, static methods cannot use instance variables (which are unique to each instance of the class).
Static methods are invoked on the class itself, not a particular object of the class. A good example of the use of static variables and methods is the Math class in Java. Rather than writing:
Math m = new Math();m.sqrt(25); //find the square root of 25
we instead write
Math.sqrt(25); //find the square root of 25Math.PI; //the value of pi-- this is a static variable in the Math class
To create static variables and/or methods, add the keyword static to the declaration, as in:
public class StaticDemo{// non-static variablesprivate int age;//static variablesprivate static int count = 0;// constructorpublic StaticDemo(){age = 5;count = count + 1; //increase the count of objects created}// static method that displays the countpublic static void displayCount(){System.out.println(count);}// non-static methodspublic void setAge(int newAge){age = newAge;}public void displayAge(){System.out.println("The age of this person is " + age);}}
In the example above, the static variable count is used to count how many times the constructor has created an object. It’s set to zero to begin, then increases by one each time the constructor executes. When a new object is created from this class, it does not get its “own” count variable-- rather, it shares it with the other instances of the class.
The static method getCount returns the value of count. Note that getCount() would not be able to use the variable x in this case, because x is not itself static (meaning each object of the class will have a different value for x). To call the getCount() method, we’d write StaticDemo.getCount().
Beginning programmers often confuse static with final. These are not the same. The final keyword means that--once assigned-- the value of a variable will not change. Static variables can change value; they are static in the sense that they are only declared once (for the whole class).
Let’s take a look at how the StaticDemo class might be used by another class.
public class StaticRunner {public static void main(String[] args) {//create two instances of StaticDemo and set agesStaticDemo sd1 = new StaticDemo();sd1.setAge(26);StaticDemo sd2 = new StaticDemo();sd2.setAge(1);//ages are different for each (non-static)sd1.displayAge();sd2.displayAge();//count is the same (static)-- we've created 2sd1.displayCount();sd2.displayCount();//static methods are usually called on the class itselfStaticDemo.displayCount();}}
The output is:
The age of this person is 26
The age of this person is 1
2
2
2
The "this" keyword
The keyword this is best understood by example. Suppose you have a class with a field called age and you have a setAge method.
public class Person{...private int age;...public void setAge(int a){age = a;}...}
You might use the identifier newAge for the method’s parameter, because you’ve already used the identifier age to represent the instance variable. Recall that variables declared as parameters in a method are only visible (local) to that method-- as opposed to fields, that are visible to all methods in the class.
But wouldn’t it make more sense to call the parameter age (because that’s what it is, after all)?
The problem with doing that is that the compiler needs to tell the two apart (the local variable for the method vs. the instance variable). This is accomplished with the “this” keyword, as follows:
public class Person{...private int age;...public void setAge(int age){this.age = age;}...}
When a method’s local variable and an instance variable have the same name (such as age above), the use of that name refers to the local variable. To refer instead to the instance variable, preface the identifier with this. this.age refers to the age field of the object to which the method is being applied (think of it as “the age for this object”). Note that some other languages use the keyword self to mean the same thing.
in most IDEs, you can get a sense for this by selecting (double-clicking) a variable. Typically, all other occurrences of that variable will then highlight. If you click either age variable above, you can see where else it is being used.
this can also be used when a method has a parameter that is another object of the same type, as follows:
public class Person{...public greetAnotherPerson(Person p){System.out.println("Hello, " + p.getName() + "! My name is "+ this.getName();}
Note that the object using this method will be a Person, but the parameter for the method is also a(nother) Person object. To tell them apart, we use this to refer to the Person object to which the method is applied, as in
Person person1 = new Person();Person person2 = new Person();person1.greetAnotherPerson(person2); //”this” refers here to person1
Note that the this keyword is only required when there’s a potential conflict in identifiers. The use below is not necessary (but will work fine).
public class Person{...private int age;...public void printAge(){System.out.println(this.age); //same as System.out.println(age);}...}
A Guide to Java