Introduction
Every day, new technology is deployed to the market in the same field. For example, in the web development field every day there is a new framework. So, what is the solution?
The solutions are the basics and the principles of industry. This allows you to understand any new technology simply because they are all built on the same principles. And therefore, in this article I will begin a journey discussing the most important topics and principles of the field of computers and information. This will be done with samples of this book which is talking about object-oriented analysis and design.
Who Will Find This Book Useful?
- Developers without formal computer science background.
- Developers who find it hard to catch new technologies.
In Part 1 (Chapter 1: Introduction) we saw that the fundamental program structure in an object-oriented program is the object. We also outlined the concept of a class.
First, before anything, go and grab a coffee! 🙂
Chapter 2: Basics of Object-Oriented Programming
In this chapter:
- Describe in detail how to construct a class. We will use the programming language Java.
- Introduce the Unified Modelling Language (UML).
- Discuss interfaces, a concept that helps us specify program requirements and demonstrate its uses.
2.1 The Basics
A class is a design that can be reused any number of times to create objects. For example, consider an object-oriented system for a university. There are student objects, instructor objects, staff member objects, and so on. Before such objects are created, we create classes that serve as blue-prints for students, instructors, staff members, and courses as follows:
public class Student { // code to implement a single student } public class Instructor { // code to implement a single instructor } public class StaffMember { // code to implement a single staff member } public class Course { // code to implement a single course }
The above definitions show how to create four classes, without giving any details. The token class is a keyword that says that we are creating a class.
We have thus created four classes Student, Instructor, StaffMember, and Course.
The token public is another keyword that makes the corresponding class available throughout the file system.
How to create objects using these classes?
The process of creating an object is also called instantiation. Each class introduces a new type name.
new Student();
The new operator causes the system to allocate an object of type Student with enough storage for storing information about one student. The operator returns the address of the location that contains this object.
Once we instantiate a new object, we must store its reference somewhere, we create a variable of type Student.
Student harry;
Thus, we can write:
harry = new Student();
We cannot write:
harry = new Instructor();
Because harry is of type Student, which has no relationship to Instructor.
2.2 Implementing Classes
We certainly would like the ability to give a student a name. Given a student object, we should be able to specify that the student’s name is “Tom” or “Jane”, or in general some string. This is sometimes referred to as a behavior of the object. We can think of student objects having the behavior that they respond to assigning a name. For this purpose, we modify the code as below:
public class Student { // code for doing other things public void setName(String studentName) { // code to remember the name } }
The code that we added is called a method. The method’s name is setName. A method is like a procedure or function in imperative programming in that it is a unit of code that is not activated until it is invoked.
Here we have put void in front of the method name meaning that the method returns nothing.
Unlike functions and procedures, methods are usually invoked through objects. The setName() method is defined within the class Student and is invoked on objects of type Student.
Student aStudent = new Student(); aStudent.setName("Ron");
The method setName() is invoked on that object referred to a Student. Intuitively, the code within that method must store the name somewhere. Remember that every object is allocated its own storage. This piece of storage must include space for remembering the name of the student.
public class Student { private String name; public void setName(String studentName) { name = studentName; } public String getName() { return name; } }
Fields: Inside the class we have defined the variable name of type String. It is called a field. A field is a variable defined directly within a class and corresponds to an attribute. Every instance of the object will have storage for the field.
Let us examine the code within the method setName(). It takes in one parameter, studentName, and assigns the value in that String object to the field name. It is important to understand how Java uses the name field. Every object of type Student has a field called name.
The getName() method retrieves the contents of the name field and returns it. To illustrate this further, consider two objects of type Student.
Student student1 = new Student(); Student student2 = new Student(); student1.setName("John"); student2.setName("Mary"); System.out.println(student1.getName()); System.out.println(student2.getName());
Members (fields and methods for now) of a class can be accessed by writing:
<object-reference>.<member-name>
The object referred to by student1 has its name field set to “John,” whereas the object referred to by student2 has its name field set to “Mary.”
Let us write a complete program using the above code.
public class Student { // code private String name; public void setName(String studentName) { name = studentName; } public String getName() { return name; } public static void main(String[] s) { Student student1 = new Student(); Student student2 = new Student(); student1.setName("John"); student2.setName("Mary"); System.out.println(student1.getName()); System.out.println(student2.getName()); } }
This allows it to be available wherever the object is available. But what about the keyword private in front of the field name? It signifies that this variable can be accessed only from code within the class Student.
If you look like the kid in the above photo right now, I would recommend to take a break for 5 minutes.
If we write:
Student someStudent = new Student(); someStudent.name = "Mary";
outside the class, the compiler will generate a syntax error.
Fields are often defined with the private access specifier and methods are usually made public. This helps preserve data integrity.
For a more justified use of private information, consider the grade point average (GPA) of a student. Clearly, we need to keep track of the GPA and need a field for it. GPA is not something that is changed arbitrarily – it changes when a student gets a grade for a course. So making it public could lead to integrity problems because the field can be inadvertently changed by bad code written outside. Thus, we code as follows:
public class Student { // fields to store the classes the student has registered for private String name; private double gpa; public void setName(String studentName) { name = studentName; } public void addCourse(Course newCourse) { // code to store a ref to newCourse in the Student object. } private void computeGPA() { // code to access the stored courses, compute and set the gpa } public double getGPA() { return gpa; } public void assignGrade(Course aCourse, char newGrade) { // code to assign newGrade to aCourse computeGPA(); } }
We now write code to utilize the above idea.
Student aStudent = new Student(); Course aCourse = new Course(); aStudent.addCourse(aCourse); aStudent.assignGrade(aCourse, ’B’); System.out.println(aStudent.getGPA());
The above code creates a Student object and a Course object. It calls the addCourse() method on the student, to add the course to the collection of courses taken by the student, and then calls assignGrade(). Note the two parameters: aCourse and ’B’. The implied meaning is that the student has completed the course (aCourse) with a grade of ’B’. The code in the method should then compute the new GPA for the student using the information presumably in the course (such as number of credits) and the number of points for a grade of ‘B’.
2.2.1 Constructors
Here we set the name of the student after creating the object. This is somewhat unnatural. It would be convenient to store the student’s name in the object as we create the student object. Java and other object-oriented languages allow the initialization of fields by using
what are called constructors. A constructor is like a method in that it can have an access specifier (like public or private), a name, parameters, and executable code. However, constructors have the following differences or special features:
- Constructors cannot have a return type: not even void.
- Constructors have the same name as the class in which they are defined.
- Constructors are called when the object is created.
For the class Student we can write the following constructor.
public Student(String studentName) { name = studentName; }
There is no return type.
Let us rewrite the Student class with this constructor and a few other modifications.
public class Student { private String name; private String address; private double gpa; public Student(String studentName) { name = studentName; } public void setName(String studentName) { name = studentName; } public void setAddress(String studentAddress) { address = studentAddress; } public String getName() { return name; } public String getAddress() { return address; } public double getGpa() { return gpa; } public void computeGPA(Course newCourse, char grade) { // use the grade and course to update gpa } }
We now maintain the address of the student and provide methods to set and get the name and the address.
With the above constructor, an object is created as below:
Student aStudent = new Student("John");
When the above statement is executed, the constructor is called with the given parameter, “John.” This gets stored in the name field of the object.
As a result, the following is no longer legal because there is no constructor with no arguments.
Student aStudent = new Student();
A class can have any number of constructors. They should all have different signatures – that is, they should differ in the way they expect parameters. The following adds two more constructors to the Student class.
public class Student { private String name; private String address; private double gpa; public Student(String studentName) { name = studentName; } public Student(String studentName, String studentAddress) { name = studentName; address = studentAddress; } public Student() { // default constructor } public void setName(String studentName) { name = studentName; } public void setAddress(String studentAddress) { address = studentAddress; } public String getName() { return name; } public String getAddress() { return address; } public double getGpa() { return gpa; } public void computeGPA(Course newCourse, char grade) { // use the grade and course to update gpa } }
Notice that all constructors have the same name, which is the name of the class. One of the new constructors accepts the name and address of the student and stores it in the appropriate fields of the object. The other constructor accepts no arguments and does nothing: as a result, the name and address fields of the object are null.
2.2.2 Printing an Object
There is a method called toString() in the class. This method contains code that tells Java how to convert the object to a String.
public String toString() { // return a string }
Whenever an object is to be converted to a String, Java calls the toString() method on the object just as any other method. The method call System.out.println() attempts to convert its arguments to the string form. So it calls the toString() method.
We can complete the toString() method for the Student class as below:
public String toString() { return "Name " + name + " Address " + address + " GPA " + gpa; }
2.2.3 Static Members
Sometimes, we need fields that are common to all instances of an object. In other words, such fields have exactly one instance and this instance is shared by all instances of the class. Such fields are called static fields. In contrast, fields maintained separately for each object are called instance fields. Let us turn to an example. Most universities usually have the rule that students not maintaining a certain minimum GPA will be put on academic probation.
We would like to introduce a field for keeping track of this minimum GPA. Since the value has to be the same for all students, it is unnecessary to maintain a separate field for each student object.
Suppose we decide to call this new field, minimumGPA, and make its type double. We define the variable as below:
private static double minimumGPA;
Suppose we need to modify this field occasionally and that we also want a method
that tells us what its value is. We typically write what are called static methods for
doing the job.
public static void setMinimumGPA(double newMinimum) { minimumGPA = newMinimum; } public static double getMinimumGPA() { return minimumGPA; }
In the next article, I will continue this topic.