Skip to content

Java Class Walkthrough

This is a full implementation of a Java class, annotated so you know what's what. (Feedback is welcome: ted@SpiralLearningLLC.com)

Package

1
package com.welltestedlearning.kiosk;
  • package is a Java keyword that tells Java the name of the package (namespace) this class is in.

    Default Package

    If you don't have package in your class, it is put in a "default" package that has no name. In general, this is not recommended and you should always put all classes (and interfaces, and enums) into a named package.

Import

2
3
import java.util.ArrayList;
import java.util.List;
  • import tells the compiler which package to look at for classes you're using that are not in the current package. In this case, we don't need to import anything from the com.welltestedlearning.kiosk package, but we do need to import the List and ArrayList classes.

Class Declaration

Finally we get to declaring the MealOrder class itself.

4
public class MealOrder extends Order {
  • public indicates that this class is visible from any other class in the system.

  • class means we're defining a class named MealOrder. This class' name has two words, meal and order, so when we combine them into a single word, we use camel-case with the first letter capitalized.

  • extends is used for inheriting, or subclassing from another class, in this case a class called Order. (Remember that class names start with an upper-case letter.)

    Reading extends

    We would read this as: MealOrder subclasses Order or MealOrder inherits from Order.

Member Variable

Here we're declaring a member (or instance, or non-static) variable, named items that's of type List<MenuItem> and points to (references) an instance of an ArrayList.

5
  private List<MenuItem> items = new ArrayList<>();
  • private here indicates that only (non-static) code within this class (e.g., inside non-static methods) can access this variable. Other classes cannot even see that it exists.

    • Because it's a variable, it starts with an initial lowercase letter and follows the camel-case form.
  • List<MenuItem> is a List (a Java Collection class) that is holding objects of type MenuItem.

    Note

    This list can hold instances of MenuItem, or subclasses of MenuItem, or any class that implements MenuItem (though only if Menuitem is an interface).

  • new is how instances of a class are created (or instantiated) by calling the target class' constructor (in this case ArrayList(), the no-argument constructor).

    • Since we already defined the types of objects this list can hold (MenuItem), we don't need to repeat that, so we can use the shorthand: <>.

Static Variable

Here we declare a static variable of type int to keep track of the number of orders:

6
  private static int orderCount = 0;
  • private means it's only accessible by code inside of this class.

  • static here means that there's only one orderCount for any and all instances of this class. We say that this variable belongs to the class and not to an instance (or object). It's accessible from inside of any constructor and any method -- static or non-static.

Constant

7
  private static final int ORDER_LIMIT = 10;

ORDER_LIMIT here is a constant, that is, it cannot be changed during runtime, and there's only one copy of it due to the static keyword. In addition, because it's marked as private, it can only be accessed from code within this class.

Static Method

 8
 9
10
  public static MealOrder createBurgerOnlyOrder(BurgerOption burgerOption) {
    return new MealOrder(burgerOption);
  }

This static method is a creation method (not to be confused with the factory method pattern -- see this article to learn about the difference and purpose). We also have a constructor that looks similar, but creation methods are useful when you end up creating lots of constructors that vary slightly. See this article that discusses the reasoning.

Entry Point: main method

11
  public static void main(String[] args) {

This is an entry point into the application that would be executed if you did

java MealOrder

at a terminal command line. Entry points must always have the signature of public static void main(String[] args) so that the Java runtime knows what to look for.

12
13
14
    MealOrder drinkOrder = new MealOrder();
    drinkOrder.addDrink(Drink.DRINK_LARGE);
    drinkOrder.display();
  • 12 Here we're declaring a variable named drinkOrder (initial lowercase letter), which points to (references) a newly created instance of MealOrder by calling the default (no-arg) constructor.

  • 13 Next we call (invoke) the addDrink method (a non-static method) and pass in a constant DRINK_LARGE (all uppercase) that would be found in the Drink class.

  • 14 Finally we invoke the display() method.

15
16
17
    MealOrder burgerOrder = createBurgerOnlyOrder(BurgerOption.REGULAR);
    burgerOrder.display();
  }

In this part of the main method, 15 we invoke the creation method that was defined above, passing in the constant REGULAR found in the BurgerOption class (which is probably an enum given the suffix Option.

Calling Static Method

Note that we didn't need to specify the class name MealOrder when invoking the createBurgerOnlyOrder method, since it's in the current class, so the current class is assumed.

We end the main method 16 by invoking display() on this second instance of MealOrder.

Constructors

The first constructor is the "no argument" constructor:

18
  public MealOrder() {

Unlike other methods, constructors don't have a name, though they look like they have the same name as the class. Another way of looking at the constructor is like this:

public MealOrder <init>() {

This makes it more clear that the return value of the constructor is an instance of the class. In fact, <init> is the true name of a constructor, but only used internally by the compiler, so when we write the constructor, we say that the name of the constructor is the same as (and must match) the name of the class.

19
20
21
22
23
    if (orderCount > ORDER_LIMIT) {
      throw new IllegalStateException("Too many orders!");
    }
    orderCount = orderCount + 1;
  }

We first check to see if the static variable, orderCount, exceeded the order limit (a constant, being all uppercase), and if so, we throw an instance (created by the new) of the IllegalStateException to abort the creation of the MealOrder. If we're fine, we increment the order count and the constructor completes successfully.

Static Variable Naming

Some coding styles use a prefix of s_ for static variables and m_ for member variables. There are also coding styles that use _ and __ (single- and double-underscore) as prefixes to differentiate static and member variables. These styles have become less common as IDEs, such as IntelliJ IDEA and Eclipse, color such variables differently, so you no longer need the name to tell you what's what.

If your code has so many variables that you can't easily tell them apart, it might be time for some refactoring. :)


This constructor takes a single argument (a reference to a BurgerOption):

24
25
26
27
  public MealOrder(BurgerOption burger) {
    this();
    addBurger(burger.name().toLowerCase());
  }
  • The this(); statement (25) is how we call the first constructor. We want to invoke the no-arg constructor so that the order limit code is executed, but without having to duplicate that code here.

    The Meaning of this

    Since constructors don't have a name that we can use, Java uses this as a way of saying "hey, call the constructor for this class". You will also see this used to refer to the current instance of the object in order to access member variables, e.g., this.items = null is the same as items = null;. Most of the time you don't need to prefix member variables with this, unless there's naming collision, e.g., in this method

    private int limit = 0;
    
    public void setLimit(int limit) {
      limit = limit;
    }
    

    it's unclear which limit is which, since there's the member variable limit, and the parameter limit. In this case you can tell the Java compiler which one you mean by doing:

    this.limit = limit;
    

    This way the compiler knows that you're assigning the value of the parameter limit to the member variable this.limit.

    Also note that constructors can only be called from other constructors.

  • We then add a new burger (26) by extracting the name, converting it to lowercase, and invoking the Burger's constructor.

    Method Chaining

    This sequence of calling a method right after another method is called chained invocations. It's exactly the same as if we did:

    String name = burger.name();
    String nameLower = name.toLowerCase();
    add(new Burger(nameLower));
    
    but since we don't need these intermediate variables, we can chain them together: burger.name().toLowerCase().

Non-Static Methods

The meat of most of your application will be in non-static methods, called instance or member methods -- or sometimes just methods.

Public Methods

Here's a public method, which means any other code that has an instance of the class can call it:

28
29
30
  public void addBurger(String burgerType) {
    items.add(new Burger(burgerType));
  }

So, if you have MealOrder meal = new MealOrder(), you can do meal.addBurger("cheeseburger").

Private Methods

These methods are private, meaning only other methods in the same class can call them. Private methods are a great way to give meaningful names to fragments of code: instead of having 30 lines of code in a public method, it might be more readable to have that method call several private methods.

31
32
33
34
35
36
37
38
39
40
41
  public void addDrink(String drinkType) {
    addDrink(new Drink(drinkType));
  }

  private addDrink(Drink drink) {
    addItem(drink);
  }

  private addItem(MenuItem item) {
    items.add(item);
  }

Here (31), the public addDrink() method calls (or delegates to) the internal addDrink() method(35) that takes a Drink object instead of just a String, which itself delegates the work to the private addItem method(39) that takes a more general MenuItem object.

That's a Wrap

That wraps up the dive into all the parts that make up a fairly typical Java class. Feedback or questions are always welcome at: ted@SpiralLearningLLC.com.