CS61B(2): Define and Use Classes

This is the lecture note of CS61B - Lecture 2.

Compilation

If you use an IDE(Integrated Development Environment), you can just click run button and the program will be executed directly. But what happened under the hood? let's see a basic process of executing Java code.

Defining and Instantiating Classes

Let's define a Dog class only with a "makeNoise" method.

1
2
3
4
5
public class Dog {
public static void makeNoise() {
System.out.println("Bark!");
}
}

Since there is no main method, we cannot run the above code directly. To run it, we create another class called DogLauncher.

1
2
3
4
5
6
/** The DogLauncher class will test drive the Dog class. */
public class DogLauncher {
public static void main(String[] args) {
Dog.makeNoise(); // Bark!
}
}

In the real world, different dogs yell differently. How to deal with it?

To make it more natural to represent the entire universe of dogs, we use the key feature of Java:

  • classes can contain not just functions (a.k.a. methods), but also data.
  • classes can be instantiated as objects.

The Dog class provides a bludeprint that all Dog objects will follow.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Dog {
public int weightInPounds; // instance variables

/** constructor: determines how to instantiate the class */
public Dog(int w) {
weightInPounds = w;
}

// instance method, a.k.a non-static method
public void makeNoise() {
if (weightInPounds < 10) {
System.out.println("yip!");
} else if (weightInPounds < 30) {
System.out.println("bark!");
} else {
System.out.println("wooof!");
}
}
}
1
2
3
4
5
6
7
/** The DogLauncher class will test drive the Dog class */
public class DogLauncher {
public static void main(String[] args) {
Dog d = new Dog(50); // create instances of Dog
d.makeNoise(); // wooof!
}
}

Notice the method makeNoise above is non-static now, meaning it should be invoked by an instance of the class.


Key differences between static methods and non-static (a.k.a. instance) methods:

  • Static methods are invoked using the class name, e.g. Dog.makeNoise( );
  • Instance methods are invoked using an instance name, e.g. maya.makeNoise( );
  • Static methods can’t access “my” instance variables, because there is no “me”.
    • for example: d.weightInPounds is ok, Dog.weightInPounds will be wrong.

Class can have a mix of static and non-static memebers (methods and variables).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class Dog {
public int weightInPounds; // instance variables
public static String binomen = "Canis familiaris"; // static variable

/** constructor: determines how to instantiate the class */
public Dog(int w) {
weightInPounds = w;
}

public void makeNoise() {
if (weightInPounds < 10) {
System.out.println("yip!");
} else if (weightInPounds < 30) {
System.out.println("bark!");
} else {
System.out.println("wooof!");
}
}

// static method
public static Dog maxDog(Dog d1, Dog d2) {
if (d1.weightInPounds > d2.weightInPounds) {
return d1;
}
return d2;
}

// non-static method
public Dog maxDog(Dog d2) {
// this: the current object
if (this.weightInPounds > d2.weightInPounds) {
return this;
}
return d2;
}
}

Notice the static variable binomen. Although you can use an instance to call it, it's a bad style.

Remeber, if you declare a static member, use class instead of instance to access it, i.e. Dog.binomen .

Arrays of Objects

To create an array of objects, you need 2 steps:

  • First use the new keyword to create the array.
  • Then use new again for each object that you want to put in the array.
1
2
3
4
Dogs[] dogs = new Dog[2];
dogs[0] = new Dog(8);
dogs[1] = new Dog(20);
dogs[0].makeNoise();

Exercise

Finally, let's see an exercise.

Will the following program compile? If so, what will it print?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class DogLoop {
public static void main(String[] args) {
Dog smallDog = new Dog(5);
Dog mediumDog = new Dog(25);
Dog hugeDog = new Dog(150);

Dog[] manyDogs = new Dog[4];
manyDogs[0] = smallDog;
manyDogs[1] = hugeDog;
manyDogs[2] = new Dog(130);

int i = 0;
while (i < manyDogs.length) {
Dog.maxDog(manyDogs[i], mediumDog).makeNoise();
i = i + 1;
}
}
}

The answer is:

  • Yes, it can pass the compilation.
  • It'll print:
    • bark!
    • wooof!
    • wooof!
    • NullPointerException (since Dog[3] is null)