Java Object & Classes
Java - Objects & Classes
Section titled “Java - Objects & Classes”Java is fundamentally an Object-Oriented Programming (OOP) language. OOP models software design based on real-world objects. Key OOP concepts supported by Java include:
- Encapsulation: Bundling data (fields) and methods that operate on the data within a single unit (a class), and controlling access to the internal state.
- Inheritance: Allowing a new class (subclass) to inherit properties and methods from an existing class (superclass), promoting code reuse.
- Polymorphism: Enabling objects to take on many forms; typically, allowing a subclass object to be treated as an object of its superclass, and overriding methods for specific behavior.
- Abstraction: Hiding complex implementation details and exposing only essential features of an object or system.
This chapter focuses on the building blocks of OOP in Java: Classes and Objects.
- Class: A blueprint or template used to create objects. It defines the common properties (fields or attributes) and behaviors (methods) that all objects of that class will have. Example: A
Carclass defines properties likecolor,make,modeland behaviors likestartEngine(),accelerate(),brake(). - Object: An instance of a class. It represents a specific entity created from the class blueprint, with its own state (specific values for the fields). Example:
myBlueToyotaCamryis an object (an instance) of theCarclass, withcolorset to “blue”,maketo “Toyota”, andmodelto “Camry”.
Objects in Java
Section titled “Objects in Java”Think about real-world objects: your phone, a desk, a pet. Each has:
- State: Characteristics or attributes (e.g., a dog’s name, breed, color, age).
- Behavior: Actions it can perform (e.g., a dog can bark, wag its tail, eat, sleep).
Software objects in Java mirror this. Their state is stored in fields (also called instance variables), and their behavior is implemented through methods.
Methods operate on an object’s internal state (its fields) and are the primary way objects interact with each other.
Classes in Java
Section titled “Classes in Java”A class is the blueprint. It defines what all objects created from it will look like and how they will behave.
Basic Class Structure:
// Access Modifier class ClassName {//// // Fields (Instance Variables) - Define the state// dataType fieldName1;// dataType fieldName2;// // ...//// // Constructors - Special methods for creating objects// ClassName(parameters) {// // Initialization code// }//// // Methods - Define the behavior// returnType methodName1(parameters) {// // Method body (code)// }// // ...//}Example: A Simple Dog Class:
public class Dog { // Fields (Instance Variables) String breed; int age; String color; String name;
// Constructor public Dog(String dogName, String dogBreed, int dogAge, String dogColor) { // 'this' keyword refers to the current object being created this.name = dogName; this.breed = dogBreed; this.age = dogAge; this.color = dogColor; System.out.println("Dog object created: " + this.name); }
// Methods (Behavior) void bark() { System.out.println(name + " says: Woof!"); }
void celebrateBirthday() { this.age++; // Increment the age of this specific dog object System.out.println("Happy Birthday, " + name + "! You are now " + age + "."); }}Variable Types within a Class:
- Instance Variables (Fields): Declared inside the class but outside any method. Each object (instance) of the class gets its own copy of these variables. They represent the object’s state (e.g.,
breed,age,color,namein theDogclass). - Local Variables: Declared inside methods, constructors, or blocks. They exist only during the execution of that block of code and are not part of the object’s state.
- Class Variables (Static Fields): Declared with the
statickeyword. There is only one copy of a static variable shared among all objects of the class. Often used for constants or counters (e.g.,static final int MAX_SPEED = 100;orstatic int dogCount = 0;).
Constructors
Section titled “Constructors”Constructors are special methods used to initialize new objects. They have the same name as the class and no return type (not even void).
- Every class has at least one constructor.
- If you don’t explicitly define any constructor, the Java compiler provides a default no-argument constructor (e.g.,
public Dog() {}). - If you define any constructor (like the one in our
Dogexample), the default no-argument constructor is not automatically provided. - Constructors are invoked using the
newkeyword when creating an object. - A class can have multiple constructors with different parameter lists (constructor overloading).
Example with multiple constructors:
public class Rectangle { double width; double height;
// Constructor 1: No arguments (creates a 1x1 rectangle) public Rectangle() { this.width = 1.0; this.height = 1.0; }
// Constructor 2: Takes width and height public Rectangle(double w, double h) { this.width = w; this.height = h; }
// Constructor 3: Takes one value for a square public Rectangle(double side) { this.width = side; this.height = side; }
// Method to calculate area public double getArea() { return this.width * this.height; }}Creating an Object (Instantiation)
Section titled “Creating an Object (Instantiation)”Creating an object involves three steps, usually combined in one statement:
- Declaration: Declare a variable of the class type (
Dog myDog;). - Instantiation: Use the
newkeyword to allocate memory for the object (new). - Initialization: Call a constructor to set the initial state of the object (
Dog("Buddy", ...)).
Example:
// Combined declaration, instantiation, and initializationDog myDog = new Dog("Buddy", "Golden Retriever", 3, "Golden");Rectangle square = new Rectangle(5.0); // Calls the third constructorAccessing Instance Variables and Methods
Section titled “Accessing Instance Variables and Methods”You access an object’s instance variables (fields) and methods using the dot (.) operator on the object reference variable.
// 1. Create an objectClassName objectReference = new ClassName(parameters);
// 2. Access a field (Generally discouraged for public fields, prefer methods)// value = objectReference.fieldName;// objectReference.fieldName = newValue;
// 3. Call a method// objectReference.methodName(arguments);Example using the Dog class:
public class DogPark { public static void main(String[] args) { // Create two Dog objects Dog dog1 = new Dog("Buddy", "Golden Retriever", 3, "Golden"); Dog dog2 = new Dog("Lucy", "Poodle", 5, "White");
// Access fields (Direct access shown, but usually done via methods like getters/setters) System.out.println(dog1.name + "'s age: " + dog1.age);
// Call methods dog1.bark(); // Output: Buddy says: Woof! dog2.bark(); // Output: Lucy says: Woof!
dog1.celebrateBirthday(); // Output: Happy Birthday, Buddy! You are now 4. System.out.println(dog1.name + "'s new age: " + dog1.age); // Output: Buddy's new age: 4 }}Encapsulation and Access Modifiers
Section titled “Encapsulation and Access Modifiers”It’s standard practice in Java to make fields private to enforce encapsulation. This means they can only be accessed or modified through methods (like getters and setters) defined within the class. This prevents external code from putting the object into an invalid state.
Example with private fields and public methods (Getters/Setters):
public class SecureBankAccount { private String accountNumber; private double balance;
public SecureBankAccount(String accNumber, double initialBalance) { this.accountNumber = accNumber; // Add validation for balance if (initialBalance >= 0) { this.balance = initialBalance; } else { this.balance = 0; System.err.println("Initial balance cannot be negative. Set to 0."); } }
// Getter for balance (allows reading) public double getBalance() { return balance; }
// Getter for account number public String getAccountNumber() { return accountNumber; }
// Method to deposit (allows controlled modification) public void deposit(double amount) { if (amount > 0) { balance += amount; } else { System.err.println("Deposit amount must be positive."); } }
// Method to withdraw (allows controlled modification) public boolean withdraw(double amount) { if (amount > 0 && amount <= balance) { balance -= amount; return true; // Success } else { System.err.println("Withdrawal failed: Invalid amount or insufficient funds."); return false; // Failure } }}Access Modifiers (public, private, protected, default) control the visibility of classes, fields, and methods. They are crucial for encapsulation and API design.
Source File Declaration Rules
Section titled “Source File Declaration Rules”Keep these rules in mind when organizing your Java code:
- Each source file (
.javafile) can contain only onepublicclass. - The name of the source file must exactly match the name of the
publicclass it contains (e.g., theDogclass must be in a file namedDog.java). - A source file can contain multiple non-
public(package-private) classes. - If the class is part of a package, the
packagedeclaration must be the very first statement in the file. importstatements, if present, must appear between thepackagestatement (if any) and the class declaration(s).packageandimportstatements apply to all classes within the source file.
Packages and Imports
Section titled “Packages and Imports”Packages are used to organize related classes and interfaces into namespaces, preventing naming conflicts and improving code structure (e.g., java.util, com.mycompany.myapp.ui).
Import statements allow you to use classes from other packages without specifying their full qualified name (package + class name) every time. Example: import java.util.ArrayList; lets you use ArrayList instead of java.util.ArrayList.
A Simple Case Study: Employee Management
Section titled “A Simple Case Study: Employee Management”Let’s create two classes: Employee (the blueprint) and EmployeeTest (to create and use Employee objects).
1. Employee.java:
package com.example.hr; // Example package declaration
import java.time.LocalDate;import java.time.Period;
public class Employee { // Using private fields for encapsulation private String name; private String designation; private double salary; private LocalDate hireDate;
// Constructor public Employee(String name, String designation, double salary, LocalDate hireDate) { this.name = name; this.designation = designation; this.salary = salary; // Consider adding validation this.hireDate = hireDate; }
// Getter methods public String getName() { return name; }
public String getDesignation() { return designation; }
public double getSalary() { return salary; }
public LocalDate getHireDate() { return hireDate; }
// Setter methods (optional, only if modification is allowed) public void setDesignation(String designation) { this.designation = designation; }
public void setSalary(double salary) { if (salary >= 0) { // Basic validation this.salary = salary; } else { System.err.println("Salary cannot be negative."); } }
// Method to calculate years of service public int getYearsOfService() { return Period.between(hireDate, LocalDate.now()).getYears(); }
// Method to print employee details public void printEmployeeDetails() { System.out.println("---------------------------"); System.out.println("Name: " + name); System.out.println("Designation: " + designation); System.out.printf("Salary: $%.2f%n", salary); // Formatted output System.out.println("Hire Date: " + hireDate); System.out.println("Years of Service: " + getYearsOfService()); System.out.println("---------------------------"); }}2. EmployeeTest.java (in the same package or import the Employee class):
package com.example.hr; // Same package as Employee
// Or if in a different package:// import com.example.hr.Employee;
import java.time.LocalDate;import java.time.Month;
public class EmployeeTest {
public static void main(String[] args) { // Create Employee objects using the constructor Employee empOne = new Employee("James Smith", "Senior Software Engineer", 95000.00, LocalDate.of(2019, Month.MARCH, 15)); Employee empTwo = new Employee("Mary Anne", "Software Engineer", 72000.00, LocalDate.of(2021, Month.JULY, 1));
// Use methods to interact with the objects System.out.println("Initial Employee Details:"); empOne.printEmployeeDetails(); empTwo.printEmployeeDetails();
// Modify an object using a setter method System.out.println("\nPromoting " + empTwo.getName() + "..."); empTwo.setDesignation("Senior Software Engineer"); empTwo.setSalary(90000.00);
System.out.println("\nUpdated Employee Details:"); empOne.printEmployeeDetails(); // Unchanged empTwo.printEmployeeDetails(); // Shows promotion }}To compile and run (assuming files are in the correct package structure):
# Navigate to the base directory containing the 'com' foldercd path/to/your/project/src # Or similar base path
# Compile both Java files (use -d to specify output directory)mkdir ../bin # Create a directory for compiled classes (optional but good practice)javac -d ../bin com/example/hr/Employee.java com/example/hr/EmployeeTest.java
# Run the EmployeeTest class (specify classpath)java -cp ../bin com.example.hr.EmployeeTestExpected output will show the details of the two employees, followed by the updated details for Mary Anne after her promotion.
What’s Next?
Section titled “What’s Next?”Understanding classes and objects is fundamental. The next chapters will delve deeper into related concepts like inheritance, polymorphism, and basic data types in Java.