How would you instantiate the employee class from a main method located in another class?

We'll now begin our journey into the world of object-oriented programming. We'll start with focusing on describing concepts and data using objects. From there on, we'll learn how to add functionality, i.e., methods to our program.

Object-oriented programming is concerned with isolating concepts of a problem domain into separate entities and then using those entities to solve problems. Concepts related to a problem can only be considered once they've been identified. In other words, we can form abstractions from problems that make those problems easier to approach.

Once concepts related to a given problem have been identified, we can also begin to build constructs that represent them into programs. These constructs, and the individual instances that are formed from them, i.e., objects, are used in solving the problem. The statement "programs are built from small, clear, and cooperative objects" may not make much sense yet. However, it will appear more sensible as we progress through the course, perhaps even self-evident.

Classes and Objects

We've already used some of the classes and objects provided by Java. A class defines the attributes of objects, i.e., the information related to them [instance variables], and their commands, i.e., their methods. The values of instance [i.e., object] variables define the internal state of an individual object, whereas methods define the functionality it offers.

A Method is a piece of source code written inside a class that's been named and has the ability to be called. A method is always part of some class and is often used to modify the internal state of an object instantiated from a class.

As an example, ArrayList is a class offered by Java, and we've made use of objects instantiated from it in our programs. Below, an ArrayList object named integers is created and some integers are added to it.

// we create an object from the ArrayList class named integers
ArrayList integers = new ArrayList[];

// let's add the values 15, 34, 65, 111 to the integers object
integers.add[15];
integers.add[34];
integers.add[65];
integers.add[111];

// we print the size of the integers object
System.out.println[integers.size[]];

An object is always instantiated by calling a method that created an object, i.e., a constructor by using the new keyword.

Loading

Loading

Creating Classes

A class specifies what the objects instantiated from it are like.

  • The object's variables [instance variables] specify the internal state of the object
  • The object's methods specify what the object does

We'll now familiarize ourselves with creating our own classes and defining the variable that belong to them.

A class is defined to represent some meaningful entity, where a "meaningful entity" often refers to a real-world object or concept. If a computer program had to process personal information, it would perhaps be meaningful to define a seperate class Person consisting of methods and attributes related to an individual.

Let's begin. We'll assume that we have a project template that has an empty main program:

public class Main {

    public static void main[String[] args] {

    }
}

Let's create a class named Person. For this class, we create a separate file named Person.java. Our program now consists of two separate files since the main program is also in its own file. The Person.java file initially contains the class definition public class Person and the curly brackets that confine the contents of the class.

After creating a new file in NetBeans, the current state is as follows. In the image below, the class Person has been added to the SandboxExercise.

You can also draw a class diagram to depict a class. We'll become familiar with its notations as we go along. An empty person-named class looks like this:

A class defines the attributes and behaviors of objects that are created from it. Let's decide that each person object has a name and an age. It's natural to represent the name as a string, and the age as an integer. We'll go ahead and add these to our blueprint:

public class Person {
    private String name;
    private int age;
}

We specify above that each object created from the Person class has a name and an age. Variables defined inside a class are called instance variables, or object fields or object attributes. Other names also seem to exist.

Instance variables are written on the lines following the class definition public class Person {. Each variable is preceded by the keyword private. The keyword private means that the variables are "hidden" inside the object. This is known as encapsulation.

In the class diagram, the variables associated with the class are defined as "variableName: variableType". The minus sign before the variable name indicates that the variable is encapsulated [it has the keyword private].

We have now defined a blueprint — a class — for the person object. Each new person object has the variables name and age, which are able to hold object-specific values. The "state" of a person consists of the values assigned to their name and age.

Loading

Defining a Constructor

We want to set an initial state for an object that's created. Custom objects are created the same way as objects from pre-made Java classes, such as ArrayList, using the new keyword. It'd be convenient to pass values ​​to the variables of that object as it's being created. For example, when creating a new person object, it's useful to be able to provide it with a name:

public static void main[String[] args] {
    Person ada = new Person["Ada"];
    // ...
}

This is achieved by defining the method that creates the object, i.e., its constructor. The constructor is defined after the instance variables. In the following example, a constructor is defined for the Person class, which can be used to create a new Person object. The constructor sets the age of the object being created to 0, and the string passed to the constructor as a parameter as its name:

public class Person {
    private String name;
    private int age;

    public Person[String initialName] {
        this.age = 0;
        this.name = initialName;
    }
}

The constructor's name is always the same as the class name. The class in the example above is named Person, so the constructor will also have to be named Person. The constructor is also provided, as a parameter, the name of the person object to be created. The parameter is enclosed in parentheses and follows the constructor's name. The parentheses that contain optional parameters are followed by curly brackets. In between these brackets is the source code that the program executes when the constructor is called [e.g., new Person ["Ada"]].

Objects are always created using a constructor.

A few things to note: the constructor contains the expression this.age = 0. This expression sets the instance variable age of the newly created object [i.e., "this" object's age] to 0. The second expression this.name = initialName likewise assigns the string passed as a parameter to the instance variable name of the object created.

Loading

Defining Methods For an Object

We know how to create an object and initialize its variables. However, an object also needs methods to be able to do anything. As we've learned, a method is a named section of source code inside a class which can be invoked.

public class Person {
    private String name;
    private int age;

    public Person[String initialName] {
        this.age = 0;
        this.name = initialName;
    }

    public void printPerson[] {
        System.out.println[this.name + ", age " + this.age + " years"];
    }
}

A method is written inside of the class beneath the constructor. The method name is preceded by public void, since the method is intended to be visible to the outside world [public], and it does not return a value [void].

In addition to the class name, instance variables and constructor, the class diagram now also includes the method printPerson. Since the method comes with the public modifier, the method name is prefixed with a plus sign. No parameters are defined for the method, so nothing is put inside the method's parentheses. The method is also marked with information indicating that it does not return a value, here void.

The method printPerson contains one line of code that makes use of the instance variables name and age — the class diagram says nothing about its internal implementations. Instance variables are referred to with the prefix this. All of the object's variables are visible and available from within the method.

Let's create three persons in the main program and request them to print themselves:

public class Main {

    public static void main[String[] args] {
        Person ada = new Person["Ada"];
        Person antti = new Person["Antti"];
        Person martin = new Person["Martin"];

        ada.printPerson[];
        antti.printPerson[];
        martin.printPerson[];
    }
}

Prints:

Sample output

Ada, age 0 years Antti, age 0 years Martin, age 0 years

This as a screencast:

Loading

Loading

Loading

Changing an Instance Variable's Value in a Method

Let's add a method to the previously created person class that increments the age of the person by a year.

public class Person {
    private String name;
    private int age;

    public Person[String initialName] {
        this.age = 0;
        this.name = initialName;
    }

    public void printPerson[] {
        System.out.println[this.name + ", age " + this.age + " years"];
    }

    // growOlder[] method has been added
    public void growOlder[] {
        this.age = this.age + 1;
    }
}

The method is written inside the Person class just as the printPerson method was. The method increments the value of the instance variable age by one.

The class diagram also gets an update.

Let's call the method and see what happens:

public class Main {

    public static void main[String[] args] {
        Person ada = new Person["Ada"];
        Person antti = new Person["Antti"];

        ada.printPerson[];
        antti.printPerson[];
        System.out.println[""];

        ada.growOlder[];
        ada.growOlder[];

        ada.printPerson[];
        antti.printPerson[];
    }
}

The program's print output is as follows:

Sample output

Ada, age 0 years Antti, age 0 years

Ada, age 2 years Antti, age 0 years

That is to say that when the two objects are "born" they're both zero-years old [this.age = 0; is executed in the constructor]. The ada object's growOlder method is called twice. As the print output demonstrates, the age of Ada is 2 years after growing older. Calling the method on an object corresponding to Ada has no impact on the age of the other person object since each object instantiated from a class has its own instance variables.

The method can also contain conditional statements and loops. The growOlder method below limits aging to 30 years.

public class Person {
    private String name;
    private int age;

    public Person[String initialName] {
        this.age = 0;
        this.name = initialName;
    }

    public void printPerson[] {
        System.out.println[this.name + ", age " + this.age + " years"];
    }

    // no one exceeds the age of 30
    public void growOlder[] {
        if [this.age 

Chủ Đề