Classes and Objects

Classes and Objects in Java

Brief Introduction: In Java, everything is associated with classes and objects. Classes are templates or blueprints for creating objects, which are instances of classes. Understanding classes and objects is fundamental to programming in Java as it is a core concept of Object-Oriented Programming (OOP).

Learning Objectives

  • Understand the structure and syntax of a Java class.
  • Learn how to create and use objects from classes.
  • Grasp the concept of class members and object references.

Class Fundamentals

A class in Java is a blueprint for creating objects. It defines a datatype by bundling data and methods that work on the data into one single unit. Data or variables defined within a class are called fields, and the procedures or functions are called methods.

Syntax of a Class


public class ClassName {
    // Fields (Variables)
    int field1;
    String field2;

    // Methods
    void method1() {
        // ...
    }

    int method2() {
        // ...
        return value;
    }
}

Creating Objects

Objects are instances of a class created using the 'new' keyword. Each object has its own identity, behaviour, and state.


public class Main {
    public static void main(String[] args) {
        // Creating an object of ClassName
        ClassName obj = new ClassName();
        // Accessing class methods through the object
        obj.method1();
        // Accessing class fields through the object
        System.out.println(obj.field1);
    }
}

Building Blocks of a Class

  1. Class Members: Variables and methods within a class are called members of the class.
  2. Object References: When you create an object, you are creating an object reference that points to the object in memory.
  3. Arrays of Objects: Just like arrays of primitives, you can have arrays of objects which hold multiple objects of a class.
  4. Constructors and Destructors: Special methods that are called when an object is created or destroyed.
  5. Access Specifiers: Keywords that determine the visibility of fields and methods outside the class.
  6. 'this' Keyword: A reference to the current object, often used within an instance method or a constructor.
  7. 'static' Keyword: Used for creating class methods and variables that are shared among all objects of the class.

Understanding Class Definition and Structure

As mentioned earlier, Java classes are fundamental constructs used to create objects. A class can be considered a blueprint for creating objects that encapsulate data and methods to work on the data.

It defines a datatype by bundling data and methods that work on the data into one single unit. Data or variables defined within a class are called fields, and the procedures or functions are called methods. Here are some detailed aspects of Java classes:

Definition and Structure

A class is defined using the class keyword followed by the class name and a pair of curly braces enclosing its body. The body of a class includes fields (variables) and methods (functions) that will belong to the objects of that class.

Key Components of a Class

  • Fields: Represent the state of an object. Each object will have its own copy of the instance fields of its class.
  • Methods: Represent the behavior of the objects. Methods can modify the state of an object and interact with other objects.
  • Constructors: Special methods called when an object is instantiated. They are used to initialise the object's state.
  • Blocks: Blocks of code that are initialised when the class is loaded or when an instance is created.

Class Inheritance

Java supports single inheritance, allowing a class to inherit fields and methods from another class. Inheritance promotes code reuse and establishes a parent-child relationship between classes. This concept will be addressed in subsequent discussions.

Object Creation from Classes

Classes are used to create objects using the new keyword followed by the class constructor. The constructor initialises the new object. Here's how you might create an object of ClassName:


ClassName obj = new ClassName();

1. Class Members

Class members consist of both fields (variables) and methods (functions) that belong to the class. Fields represent the state of an object, and methods represent the behaviour.

public class Bicycle {
    // Fields - Class Members
    public int gear;
    public int speed;

    // Methods - Class Members
    public void applyBrake(int decrement) {
        speed -= decrement;
    }

    public void speedUp(int increment) {
        speed += increment;
    }
}

2. Object References

Object references are variables that hold the memory location of an object rather than the object itself. When an object is assigned to a reference variable, it's the address of the object that's copied.

public class Main {
    public static void main(String[] args) {
        // Creating an object of class Bicycle
        Bicycle myBike = new Bicycle(3, 100);

        // myBike holds the reference to the Bicycle object
        System.out.println("Current Speed: " + myBike.speed);
    }
}

3. Arrays of Objects

Java allows the creation of arrays that can hold multiple objects of a class. This is useful when managing collections of complex data types and creating structures like lists of objects.

public class Main {
    public static void main(String[] args) {
        // Creating an array of Bicycle objects
        Bicycle[] myBikes = new Bicycle[2];
        myBikes[0] = new Bicycle(3, 100);
        myBikes[1] = new Bicycle(4, 150);

        // Accessing objects from the array
        System.out.println("Bike1 Speed: " + myBikes[0].speed);
        System.out.println("Bike2 Speed: " + myBikes[1].speed);
    }
}

4. Constructors and Destructors

Constructors are special methods in a class that are called when an object of the class is created. They are used to initialise objects. Java handles object destruction through its garbage collection mechanism.

public class Box {
    double width;
    double height;
    double depth;

    // Constructor for Box.
    public Box(double w, double h, double d) {
        width = w;
        height = h;
        depth = d;
    }
}

5. Access Specifiers

Access specifiers (or access modifiers) in Java dictate the visibility of classes, fields, methods, and constructors.

Classes can be declared with various access levels which determine how other classes can interact with them. The most common are:

  • public: The class is accessible from any other class.
  • default (no modifier): The class is only accessible within its own package.
  • final: The class cannot be subclassed.
  • abstract: The class cannot be instantiated directly and must be subclassed.
public class AccessSpecifiers {
    private int privateVar = 40;
    public int publicVar = 20;
    protected int protectedVar = 30;
    int defaultVar = 10; // No modifier

    public void display() {
        System.out.println("Public Method");
    }

    private void displayPrivate() {
        System.out.println("Private Method");
    }
}

6. 'this' Keyword

The this keyword is a reference to the current object — the object whose method or constructor is being called. It eliminates ambiguity between class attributes and parameters with the same name.

public class Rectangle {
    private int x, y;
    private int width, height;

    public Rectangle(int x, int y, int width, int height) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }

    void display() {
        System.out.println("Position: (" + this.x + ", " + this.y + ")");
    }
}

7. 'static' Keyword

The static keyword in Java is primarily used for memory management. We can apply the Java static keyword with variables, methods, blocks, and nested classes. The static keyword belongs to the class rather than an instance of the class.

public class StaticExample {
    static int staticVar = 10; // Static variable

    static void displayStatic() {
        System.out.println("Static Method");
    }

    public static void main(String[] args) {
        StaticExample.displayStatic(); // Accessing static method
    }
}

Mutability in Java

Mutability refers to the ability of an object to change its state or content after it has been created. In Java, objects are mutable by default. However, designing immutable objects can lead to simpler, more reliable code that is easier to maintain.

  • Mutable Object: Its fields or contents can be changed after the object is created. Examples include StringBuilder and most custom objects unless specifically designed to be immutable.
  • Immutable Object: Once created, its state or content cannot be changed. Examples include wrapper classes like Integer, String, and BigDecimal.

Creating immutable objects in Java usually involves:

  • Declaring all fields as private and final.
  • Not providing setters.
  • Ensuring exclusive access to mutable components.

Mutability is a critical consideration in application design, affecting concurrency, security, and functional-style programming.

Introduction to Object-Oriented Programming (OOP)

Object-Oriented Programming (OOP) is a programming paradigm based on the concept of "objects", which can contain data and code: data in the form of fields (often known as attributes or properties), and code, in the form of procedures (often known as methods).

Java is a robust OOP language that supports the following OOP paradigms:

1. Encapsulation

Encapsulation is the technique of making the fields in a class private and providing access to the fields via public methods. It's a protective barrier that keeps the data and code safe within the class itself.

2. Inheritance

Inheritance is a mechanism wherein a new class is derived from an existing class. The new class, called the subclass, inherits the attributes and methods of the superclass.

3. Polymorphism

Polymorphism allows methods to do different things based on the object it is acting upon. In simple words, it allows you to define one interface and have multiple implementations.

4. Abstraction

Abstraction means hiding the complexity and only showing the essential features of the object. In Java, abstraction is achieved using abstract classes and interfaces.

These OOP concepts form the essence of Java programming and are fundamental in creating applications that are easy to maintain and extend. These concepts will be addressed in detail in subsequent discussions.

Introduction to Java Packages and Sub-packages

Understanding Packages in Java: In Java, a package is a namespace that is a set of related classes and interfaces. Conceptually you can think of packages as being similar to different folders on your computer. You might keep HTML files in one folder, images in another, and scripts or applications in yet another. Java uses file system directories to store packages.

What is a Package?

A package in Java is used to group related classes. Think of it as a folder in a file directory. We use packages to avoid name conflicts and to write a better maintainable code. Packages are divided into two categories:

  • Built-in Packages (packages from the Java API)
  • User-defined Packages (create your own packages)

Sub-packages

Sub-packages are nested packages within a package. These are used for further categorising and organising your classes and code. For instance, in a large application, you might have a package called graphics and within it sub-packages such as graphics.shapes and graphics. colours .

Why Use Packages?

  • Prevention of naming conflicts: As your application grows, you might create classes with the same name as existing classes in the Java framework or third-party libraries. Packages provide a way to distinguish your classes.
  • Access Protection: Packages can be used to control access to classes and interfaces, allowing you to define what is visible outside of the package.
  • Removing naming conflicts: If two programmers give the same name to different variables or methods, packages can act as a categorization to avoid naming conflicts.
  • Easier Access Control: You can restrict access to classes, interfaces, and methods within the package.
  • Better Organization: Packages can be used to categorise the classes and interfaces, making them easier to locate and use.

It's important to note that as you begin to create and work with Java classes, packages and sub-packages will be used extensively, often without direct realisation. It's a part of Java's structure that helps organise code and make it more maintainable and scalable. By introducing the correct terminology now, we hope to clarify these concepts as they naturally emerge and are employed in your Java programming journey.

General Conventions and Good Practices in Creating Classes and Objects in Java

Adhering to good practices and conventions is crucial for writing maintainable, efficient, and error-free code. Below are some widely accepted guidelines for creating classes and objects in Java:

  • Naming Conventions: Class names should be nouns in UpperCamelCase. Avoid using acronyms unless the acronym is much more widely used than the full term.
  • Use Access Modifiers: Define the access level of class members (fields and methods) properly using access modifiers (private, protected, public). Private should be the default choice for fields to follow encapsulation.
  • Minimize Mutability: Avoid making classes and methods mutable unless necessary. Immutable objects are easier to design, implement, and use than mutable objects.
  • Class Size: Keep classes compact and focused on a single responsibility. A class should represent a single abstraction.
  • Constructor Overloading: Overload constructors carefully and ensure they are distinct and intuitive. Use constructor chaining to avoid code duplication.
  • Avoid Excessive Public Methods: Limit the number of public methods to minimise the class's surface area. This makes it less susceptible to changes and easier to maintain.
  • Documenting: Use Javadoc comments to document the purpose of the class, its methods, and its non-obvious behaviours. This is especially important for public APIs.
  • Use 'this' Keyword: Use 'this' to refer to the current instance within an instance method or a constructor. This makes the code more readable and avoids confusion with local variables.
  • Static Members: Use static fields and methods judiciously. They are part of the class itself, not the objects, and should be used for class-wide properties and behaviours.
  • Consistent Style: Be consistent in naming, indentation, and overall code style throughout all the classes in a project. This makes the code more readable and maintainable.

Following these conventions and practices will lead to better code quality, easier maintenance, and a more consistent development experience. Always keep learning and adapting to new and better practices as you grow as a Java developer.

Best Practices

When designing and using classes, it's important to:

  • Encapsulate your data by making fields private and providing public getter and setter methods.
  • Design for inheritance or prohibit it using the final keyword.
  • Use meaningful names for classes, fields, and methods to clarify their purpose.
  • Keep classes focused on a single responsibility.

Understanding classes is crucial for effective object-oriented programming in Java. They are the building blocks that allow developers to create complex and flexible applications.

Additional Reading

To deepen your understanding of Classes and Objects in Java, consider exploring the following topics:

  • Encapsulation and Data Hiding
  • Polymorphism in Java
  • Java Abstract Classes and Interfaces

Understanding the Main Method in Java

Java files that are organised within a folder or its sub-folders can be read and compiled by the Java compiler. In this context, the main method serves as the entry point for executing Java applications. Each Java class can have its own main method, but only one main method is designated as the entry point for a particular execution.

  • Java: The main method must be public, static, return void, and accept a String array as a parameter (often named args). It's static because it must be accessible for the runtime engine to invoke it without creating an instance.
  • Python: Python doesn't require a main method; scripts are executed line by line. However, a block under if __name__ == '__main__' is used to denote executable sections of code typically used in the same way as a main method.
  • C/C++: Similar to Java, C and C++ use a main function as the entry point, but there are no class structures wrapping the main function. It's usually returning an integer to report the exit status of the application.

While each class in Java can have its own main method, typically only one class, the class containing the main method that starts the application, is executed when the application starts. For large applications, it's common to keep the entry point in a separate class dedicated to initialisation and configuration.

Each class should ideally be in a separate file named after the class itself to promote better organisation and readability, especially in large projects. This is a standard convention in Java development.

Java files that are in a folder/sub-folder will be read, and the main method will serve as the entry point and all the class definitions and resources will be multiple main methods should n

Points to Remember

  • Blueprint for Objects: Classes are templates or blueprints for objects. They define the properties (fields) and capabilities (methods) that their objects will have.
  • Access Modifiers: Use access modifiers (private, public, protected) wisely to encapsulate your data and control class member visibility.
  • Object Instantiation: Use the 'new' keyword followed by the constructor to create new instances of a class, known as objects.
  • Main Method: The 'main' method is the entry point of the application in Java, marked as public static void main(String[] args). It's where the program starts running.
  • Inheritance: Java supports single inheritance, allowing classes to inherit characteristics from other classes, promoting code reusability and logical hierarchy.
  • 'this' keyword: Use 'this' to reference the current object within instance methods or constructors. It's useful to differentiate class fields from parameters or variables.
  • 'static' keyword: Members marked as static belong to the class itself rather than any particular object instance, useful for constants or utility methods.
  • Constructors: Constructors initialise new objects. They have the same name as the class and no return type.
  • Encapsulation: Encapsulate your classes using private fields and public getters/setters to protect data and control modifications.
  • File Structure: Typically, each class is in its own file with the filename matching the class name for clarity and organisation.
  • Code Style: Follow consistent naming conventions and coding styles for readability and maintainability.
  • Documentation: Use comments and Javadocs to document classes and methods, explaining their purpose, parameters, and return values.
  • Mutability: Consider the mutability of your classes. Whenever possible, prefer immutability to reduce errors and complexity.

Java Programming Practice: Classes and Objects

Enhance your learning by working on the following exercise programs. Each program should clearly state the inputs and expected outputs. Post file reading modules, consider inputs based on reading an input file.

Program 1: Student Class Creation and Instantiation

Question: Create a class named 'Student' with a String variable 'name' and an integer variable 'roll_no'. Initialise an object of the class with the name "John" and roll number 2. Display the assigned values on the screen.

Requirements: Ensure that the class has a constructor that initialises the name and roll number. The program should display the output of the name and roll number using the created object.


class Student {
    String name;
    int roll_no;

    public Student(String name, int roll_no) {
        this.name = name;
        this.roll_no = roll_no;
    }

    public static void main(String[] args) {
        Student student1 = new Student("John", 2);
        System.out.println("Name: " + student1.name + ", Roll Number: " + student1.roll_no);
    }
}

Running the program yields the following output

Program 2: Employee Class with ID and Name

Question: Define an 'Employee' class with a String variable 'name' and an integer 'id'. Create an object of the class with name "Alice" and id 101, and then output the details of the employee.

Requirements: The class should have an appropriate constructor to initialise the objects. Your output should print the employee's name and ID clearly.


class Employee {
    String name;
    int id;

    public Employee(String name, int id) {
        this.name = name;
        this.id = id;
    }

    public static void main(String[] args) {
        Employee emp1 = new Employee("Alice", 101);
        System.out.println("Employee Name: " + emp1.name + ", ID: " + emp1.id);
    }
}

For the rest of the programs, the snapshot of execution is not provided. Try them out yourself.

Program 3: Book Class with Title and Author

Question: Design a class 'Book' that can store a title and author name. Instantiate an object of this class with the title "Java Fundamentals" and author "John Doe", and print out the details of the book.

Requirements: The Book class should have a constructor to initialise the title and author. Ensure the output displays both the title and the author of the book.


class Book {
    String title;
    String author;

    public Book(String title, String author) {
        this.title = title;
        this.author = author;
    }

    public static void main(String[] args) {
        Book book1 = new Book("Java Fundamentals", "John Doe");
        System.out.println("Book Title: " + book1.title + ", Author: " + book1.author);
    }
}

Program 4: Rectangle Class with Length and Width

Question: Create a 'Rectangle' class with two integer variables: 'length' and 'width'. Instantiate an object with length 4 and width 5, and calculate and display the area of the rectangle.

Requirements: Your Rectangle class should have a method to calculate the area. Ensure that the object instantiation and area calculation are done in the main method and the result is printed.


class Rectangle {
    int length;
    int width;

    public Rectangle(int length, int width) {
        this.length = length;
        this.width = width;
    }

    int area() {
        return length * width;
    }

    public static void main(String[] args) {
        Rectangle rect1 = new Rectangle(4, 5);
        System.out.println("Area of Rectangle: " + rect1.area());
    }
}

Program 5: Circle Class with Radius

Question: Implement a 'Circle' class with a double variable 'radius'. Create an object with radius 3.5, compute and display the area of the circle.

Requirements: The Circle class should include a method to calculate the area. The main method should instantiate the Circle object and print the area with an appropriate message.


class Circle {
    double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    double area() {
        return Math.PI * radius * radius;
    }

    public static void main(String[] args) {
        Circle circle1 = new Circle(3.5);
        System.out.println("Area of Circle: " + circle1.area());
    }
}

Exercise Problems

In attempting the problems, make it a habit to use the conventions ClassNames and variableNames as given in the question.

Program 1: Concrete Slab Volume Calculator

Problem: Develop a class SlabVolumeCalculator to calculate the volume of a concrete slab. The program should prompt the user for the slab's length, width, and thickness and then compute the volume.

Input: Length (meters), Width (meters), Thickness (meters).

Process:

  1. Prompt the user to enter the length, width, and thickness.
  2. Calculate the volume using the formula: volume = length × width × thickness.
  3. Display the result.

Output Format: "The volume of the concrete slab is: [volume] cubic meters."

Program 2: Grade Calculator

Problem: Create a class GradeCalculator that calculates the final grade of a student. The program should take three exam scores entered by the user and compute the final grade.

Input: Three exam scores.

Process:

  1. Prompt the user to enter three exam scores.
  2. Calculate the average or final grade based on the input scores.
  3. Display the result.

Output Format: "The final grade is: [grade]."

Program 3: Temperature Converter

Problem: Implement a class TemperatureConverter to convert room temperature from Celsius to Kelvin. The user will input the temperature in Celsius, and the program will output the equivalent in Kelvin.

Input: Temperature in Celsius.

Process:

  1. Prompt the user for the room temperature in Celsius.
  2. Convert it to Kelvin using the formula: Kelvin = Celsius + 273.15.
  3. Display the result.

Output Format: "[tempCelsius]°C is [tempKelvin] K."

Program 4: Annual Rainfall Calculator

Problem: Design a class RainfallCalculator to compute the total annual rainfall. The program should accept monthly rainfall amounts from the user and sum them up to get the annual total.

Input: Twelve monthly rainfall amounts.

Process:

  1. Prompt the user to enter the rainfall for each month.
  2. Sum all the monthly rainfall amounts to get the total annual rainfall.
  3. Display the result.

Output Format: "The total annual rainfall is: [totalRainfall] mm."

Program 5: Distance Calculator

Problem: Create a class DistanceCalculator to calculate the distance between two points. The program should accept coordinates for two points (x1, y1) and (x2, y2) and compute the distance.

Input: Coordinates of two points (x1, y1, x2, y2).

Process:

  1. Prompt the user for the coordinates of two points.
  2. Calculate the distance using the formula: distance = √((x2-x1)² + (y2-y1)²).
  3. Display the result.

Output Format: "The distance between points is: [distance] meters."

Program 6: Triangle Area Calculator

Problem: Implement a class TriangleAreaCalculator that calculates the area of a triangle using Heron's formula. The program should prompt the user for the lengths of the three sides of the triangle and then compute the area.

Input: Lengths of the three sides of the triangle.

Process:

  1. Prompt the user for the lengths of the sides.
  2. Calculate the area using Heron's formula.
  3. Display the result.

Output Format: "The area of the triangle is: [area] square meters."

Program 7: Parking Charge Estimator

Problem: Develop a class ParkingChargeEstimator to calculate parking charges. The program should prompt the user for the total hours parked and then compute the parking charge based on a fixed rate.

Input: Total hours parked.

Process:

  1. Prompt the user for the total hours parked.
  2. Calculate the charge based on a predetermined rate.
  3. Display the result.

Output Format: "The total parking charge is: [charge]."

Program 8: Speed Converter

Problem: Write a class SpeedConverter to convert speed from meters per second to kilometers per hour. The user will input the speed in meters per second, and the program will output the equivalent speed in kilometers per hour.

Input: Speed in meters per second.

Process:

  1. Prompt the user for speed in meters per second.
  2. Convert the speed to kilometers per hour using the formula: km/h = m/s * 3.6.
  3. Display the result.

Output Format: "[speedMps] m/s is [speedKmph] km/h."

Program 9: Character Counter

Problem: Create a class CharacterCounter to count the number of characters in a user-provided name, excluding spaces. This program will help understand basic string operations.

Input: A name.

Process:

  1. Prompt the user to enter a name.
  2. Count the number of characters excluding spaces.
  3. Display the result.

Output Format: "The name [name] has [count] characters."

Program 10: Rectangular Prism Surface Area Calculator

Problem: Implement a class PrismSurfaceAreaCalculator to calculate the surface area of a rectangular prism. The program should prompt the user for the prism's length, width, and height and then compute the surface area.

Input: Length, width, and height of the rectangular prism.

Process:

  1. Prompt the user for the dimensions of the rectangular prism.
  2. Calculate the surface area using the formula: surface area = 2lw + 2lh + 2wh.
  3. Display the result.

Output Format: "The surface area of the rectangular prism is: [surfaceArea] square meters."