50% complete
Classes and Objects in Java
Classes and objects are the fundamental building blocks of object-oriented programming in Java. This tutorial covers how to create and use classes, instantiate objects, work with constructors, and implement the principles of object-oriented design.
What Are Classes and Objects?
Java is an object-oriented programming language where everything revolves around classes and objects. But what exactly are they?
Class
A class is a blueprint or template that defines the attributes (variables) and behaviors (methods) common to all objects of a certain kind. It's like an architectural plan for a house.
Object
An object is an instance of a class. It's a concrete entity created according to the blueprint defined by the class. Going back to our analogy, an object is like an actual house built from the architectural plan.
Class vs Object
Class (Blueprint)
- Defines properties (fields)
- Defines behaviors (methods)
- Template for creating objects
- Defined once
- No memory allocated when created
Objects (Instances)
- Has actual property values
- Can perform behaviors
- Created from class template
- Multiple can exist
- Memory allocated when instantiated
Defining a Class in Java
Let's start by creating a simple class in Java:
1// Basic class definition2public class Car {3 // Instance variables (attributes/properties)4 String make;5 String model;6 int year;7 double price;89 // Method to display car information10 void displayInfo() {11 System.out.println("Car: " + make + " " + model + " (" + year + ")");12 System.out.println("Price: $" + price);13 }14}
Let's break down the components of a class:
- Class Declaration: Starts with the keyword
class
followed by the class name. - Access Modifier:
public
means the class is accessible from any other class. - Instance Variables: Variables declared inside a class but outside any method represent the attributes of the class.
- Methods: Functions defined inside a class that represent behaviors of the class.
Creating Objects
Once you have defined a class, you can create objects (instances) of that class:
1public class CarExample {2 public static void main(String[] args) {3 // Creating objects of the Car class4 Car myCar = new Car();5 Car friendsCar = new Car();67 // Setting values for myCar8 myCar.make = "Toyota";9 myCar.model = "Camry";10 myCar.year = 2022;11 myCar.price = 25000.00;1213 // Setting values for friendsCar14 friendsCar.make = "Honda";15 friendsCar.model = "Accord";16 friendsCar.year = 2021;17 friendsCar.price = 24000.00;1819 // Displaying information20 System.out.println("My car details:");21 myCar.displayInfo();2223 System.out.println("24My friend's car details:");25 friendsCar.displayInfo();26 }27}2829// Output:30// My car details:31// Car: Toyota Camry (2022)32// Price: $25000.033//34// My friend's car details:35// Car: Honda Accord (2021)36// Price: $24000.0
The new
keyword is used to create a new instance of a class. This allocates memory for the object and returns a reference to it. Each object has its own copy of the instance variables.
Constructors
A constructor is a special method used to initialize objects. It is called when an object is created with the new
keyword. If you don't define any constructor, Java provides a default no-argument constructor.
1public class Student {2 // Instance variables3 String name;4 int age;5 String course;67 // Default constructor8 public Student() {9 name = "Unknown";10 age = 0;11 course = "Not enrolled";12 }1314 // Parameterized constructor15 public Student(String studentName, int studentAge, String studentCourse) {16 name = studentName;17 age = studentAge;18 course = studentCourse;19 }2021 // Method to display student information22 public void displayInfo() {23 System.out.println("Student Name: " + name);24 System.out.println("Student Age: " + age);25 System.out.println("Enrolled Course: " + course);26 }2728 public static void main(String[] args) {29 // Creating objects using different constructors30 Student student1 = new Student();31 Student student2 = new Student("John Doe", 20, "Computer Science");3233 System.out.println("Student 1 Details:");34 student1.displayInfo();3536 System.out.println("37Student 2 Details:");38 student2.displayInfo();39 }40}4142// Output:43// Student 1 Details:44// Student Name: Unknown45// Student Age: 046// Enrolled Course: Not enrolled47//48// Student 2 Details:49// Student Name: John Doe50// Student Age: 2051// Enrolled Course: Computer Science
Constructor Rules
- Constructor name must be the same as the class name
- Constructors don't have return types (not even void)
- Constructors can be overloaded (multiple constructors with different parameters)
- If you don't provide any constructor, Java provides a default no-argument constructor
- If you provide any constructor, Java doesn't provide the default constructor
The 'this' Keyword
The this
keyword refers to the current object instance. It's often used to distinguish between instance variables and parameters with the same name, or to call one constructor from another.
1public class Rectangle {2 // Instance variables3 private int length;4 private int width;56 // Constructor with same-named parameters7 public Rectangle(int length, int width) {8 // Using 'this' to refer to instance variables9 this.length = length;10 this.width = width;11 }1213 // Overloaded constructor for a square14 public Rectangle(int side) {15 // Using 'this' to call another constructor16 this(side, side); // Calls Rectangle(int length, int width)17 }1819 // Method to calculate area20 public int area() {21 return length * width;22 }2324 // Method to display information25 public void display() {26 System.out.println("Length: " + this.length);27 System.out.println("Width: " + this.width);28 System.out.println("Area: " + this.area());29 }3031 public static void main(String[] args) {32 Rectangle rectangle = new Rectangle(5, 3);33 Rectangle square = new Rectangle(4);3435 System.out.println("Rectangle:");36 rectangle.display();3738 System.out.println("39Square:");40 square.display();41 }42}4344// Output:45// Rectangle:46// Length: 547// Width: 348// Area: 1549//50// Square:51// Length: 452// Width: 453// Area: 16
Access Modifiers
Access modifiers control the visibility and accessibility of classes, methods, and variables. Java provides four types of access modifiers:
Access Modifier | Class | Package | Subclass | World |
---|---|---|---|---|
public | ✓ | ✓ | ✓ | ✓ |
protected | ✓ | ✓ | ✓ | ✗ |
default (no modifier) | ✓ | ✓ | ✗ | ✗ |
private | ✓ | ✗ | ✗ | ✗ |
1public class AccessModifierExample {2 // Public: accessible from anywhere3 public String publicVar = "I am public";45 // Protected: accessible within same package and subclasses6 protected String protectedVar = "I am protected";78 // Default (no modifier): accessible only within same package9 String defaultVar = "I am default";1011 // Private: accessible only within the same class12 private String privateVar = "I am private";1314 public void displayVars() {15 // Can access all variables here because we're inside the class16 System.out.println(publicVar);17 System.out.println(protectedVar);18 System.out.println(defaultVar);19 System.out.println(privateVar);20 }21}
Encapsulation and Getter/Setter Methods
Encapsulation is one of the four fundamental principles of object-oriented programming. It refers to the bundling of data (variables) and methods that operate on the data into a single unit (class), and restricting direct access to some of the object's components.
This is typically achieved by making variables private and providing public getter and setter methods:
1public class Person {2 // Private variables for encapsulation3 private String name;4 private int age;5 private double salary;67 // Constructor8 public Person(String name, int age, double salary) {9 this.name = name;10 this.setAge(age); // Using setter for validation11 this.setSalary(salary);12 }1314 // Getter for name15 public String getName() {16 return name;17 }1819 // Setter for name20 public void setName(String name) {21 this.name = name;22 }2324 // Getter for age25 public int getAge() {26 return age;27 }2829 // Setter for age with validation30 public void setAge(int age) {31 if (age > 0 && age < 120) {32 this.age = age;33 } else {34 System.out.println("Invalid age. Age must be between 1 and 120.");35 this.age = 0; // Default value36 }37 }3839 // Getter for salary40 public double getSalary() {41 return salary;42 }4344 // Setter for salary with validation45 public void setSalary(double salary) {46 if (salary >= 0) {47 this.salary = salary;48 } else {49 System.out.println("Invalid salary. Salary cannot be negative.");50 this.salary = 0; // Default value51 }52 }5354 public void displayInfo() {55 System.out.println("Name: " + name);56 System.out.println("Age: " + age);57 System.out.println("Salary: $" + salary);58 }5960 public static void main(String[] args) {61 Person person = new Person("Alice Smith", 30, 75000);62 person.displayInfo();6364 // Using getters65 System.out.println("66Using getters:");67 System.out.println("Name: " + person.getName());68 System.out.println("Age: " + person.getAge());69 System.out.println("Salary: $" + person.getSalary());7071 // Using setters72 System.out.println("73After using setters:");74 person.setName("Alice Johnson");75 person.setAge(31);76 person.setSalary(80000);77 person.displayInfo();7879 // Testing validation80 System.out.println("81Testing validation:");82 person.setAge(-5); // Invalid age83 person.setSalary(-1000); // Invalid salary84 person.displayInfo();85 }86}8788// Output:89// Name: Alice Smith90// Age: 3091// Salary: $75000.092//93// Using getters:94// Name: Alice Smith95// Age: 3096// Salary: $75000.097//98// After using setters:99// Name: Alice Johnson100// Age: 31101// Salary: $80000.0102//103// Testing validation:104// Invalid age. Age must be between 1 and 120.105// Invalid salary. Salary cannot be negative.106// Name: Alice Johnson107// Age: 0108// Salary: $0.0
Static Members
Static members (variables and methods) belong to the class rather than instances of the class. They are shared among all instances of the class.
1public class BankAccount {2 // Instance variables3 private String accountHolder;4 private double balance;56 // Static variable shared across all instances7 private static double interestRate = 0.05; // 5%8 private static int totalAccounts = 0;910 // Constructor11 public BankAccount(String accountHolder, double initialDeposit) {12 this.accountHolder = accountHolder;13 this.balance = initialDeposit;14 totalAccounts++; // Increment the total count when a new account is created15 }1617 // Instance method18 public void deposit(double amount) {19 if (amount > 0) {20 balance += amount;21 System.out.println("$" + amount + " deposited. New balance: $" + balance);22 } else {23 System.out.println("Invalid deposit amount.");24 }25 }2627 // Instance method28 public void withdraw(double amount) {29 if (amount > 0 && amount <= balance) {30 balance -= amount;31 System.out.println("$" + amount + " withdrawn. New balance: $" + balance);32 } else {33 System.out.println("Invalid withdrawal amount or insufficient funds.");34 }35 }3637 // Method that uses the static interest rate38 public void addYearlyInterest() {39 double interest = balance * interestRate;40 balance += interest;41 System.out.println("Annual interest added. New balance: $" + balance);42 }4344 // Static method to change interest rate45 public static void setInterestRate(double newRate) {46 if (newRate >= 0 && newRate <= 0.1) { // Limit between 0% and 10%47 interestRate = newRate;48 System.out.println("Interest rate changed to " + (interestRate * 100) + "%");49 } else {50 System.out.println("Invalid interest rate. Must be between 0% and 10%.");51 }52 }5354 // Static method to get total accounts55 public static int getTotalAccounts() {56 return totalAccounts;57 }5859 // Display account info60 public void displayInfo() {61 System.out.println("Account Holder: " + accountHolder);62 System.out.println("Current Balance: $" + balance);63 System.out.println("Current Interest Rate: " + (interestRate * 100) + "%");64 }6566 public static void main(String[] args) {67 System.out.println("Total accounts before: " + BankAccount.getTotalAccounts());6869 BankAccount account1 = new BankAccount("John Smith", 1000);70 BankAccount account2 = new BankAccount("Sarah Johnson", 2500);7172 System.out.println("Total accounts after: " + BankAccount.getTotalAccounts());7374 System.out.println("75Account 1:");76 account1.displayInfo();7778 System.out.println("79Account 2:");80 account2.displayInfo();8182 // Change interest rate using static method83 System.out.println("84Changing interest rate:");85 BankAccount.setInterestRate(0.06); // Change to 6%8687 // Both accounts now have the new interest rate88 System.out.println("89Account 1 after interest rate change:");90 account1.displayInfo();9192 System.out.println("93Account 2 after interest rate change:");94 account2.displayInfo();9596 // Add yearly interest to account197 System.out.println("98Adding yearly interest to account 1:");99 account1.addYearlyInterest();100 account1.displayInfo();101 }102}103104// Output:105// Total accounts before: 0106// Total accounts after: 2107//108// Account 1:109// Account Holder: John Smith110// Current Balance: $1000.0111// Current Interest Rate: 5.0%112//113// Account 2:114// Account Holder: Sarah Johnson115// Current Balance: $2500.0116// Current Interest Rate: 5.0%117//118// Changing interest rate:119// Interest rate changed to 6.0%120//121// Account 1 after interest rate change:122// Account Holder: John Smith123// Current Balance: $1000.0124// Current Interest Rate: 6.0%125//126// Account 2 after interest rate change:127// Account Holder: Sarah Johnson128// Current Balance: $2500.0129// Current Interest Rate: 6.0%130//131// Adding yearly interest to account 1:132// Annual interest added. New balance: $1060.0133// Account Holder: John Smith134// Current Balance: $1060.0135// Current Interest Rate: 6.0%
Key Points About Static Members
- Static variables are shared among all instances of a class
- Static methods can be called without creating an instance of the class
- Static methods cannot access instance variables or instance methods directly
- Static methods cannot use the
this
keyword - Non-static methods can access both static and instance members
Practical Application: A Complete Class Example
Let's put everything together with a comprehensive example of a Product class for an e-commerce system:
1public class Product {2 // Instance variables with private access (encapsulation)3 private String name;4 private String description;5 private double price;6 private int stockQuantity;7 private String category;89 // Static variables10 private static int totalProducts = 0;11 private static double taxRate = 0.08; // 8% tax1213 // Default constructor14 public Product() {15 this.name = "Unnamed Product";16 this.description = "No description available";17 this.price = 0.0;18 this.stockQuantity = 0;19 this.category = "Uncategorized";20 totalProducts++;21 }2223 // Parameterized constructor24 public Product(String name, String description, double price, int stockQuantity, String category) {25 this.name = name;26 this.description = description;27 setPrice(price); // Using setter for validation28 setStockQuantity(stockQuantity); // Using setter for validation29 this.category = category;30 totalProducts++;31 }3233 // Getters and setters34 public String getName() {35 return name;36 }3738 public void setName(String name) {39 this.name = name;40 }4142 public String getDescription() {43 return description;44 }4546 public void setDescription(String description) {47 this.description = description;48 }4950 public double getPrice() {51 return price;52 }5354 public void setPrice(double price) {55 if (price >= 0) {56 this.price = price;57 } else {58 System.out.println("Error: Price cannot be negative.");59 this.price = 0.0;60 }61 }6263 public int getStockQuantity() {64 return stockQuantity;65 }6667 public void setStockQuantity(int stockQuantity) {68 if (stockQuantity >= 0) {69 this.stockQuantity = stockQuantity;70 } else {71 System.out.println("Error: Stock quantity cannot be negative.");72 this.stockQuantity = 0;73 }74 }7576 public String getCategory() {77 return category;78 }7980 public void setCategory(String category) {81 this.category = category;82 }8384 // Instance methods85 public double getPriceWithTax() {86 return price * (1 + taxRate);87 }8889 public boolean isInStock() {90 return stockQuantity > 0;91 }9293 public void addStock(int quantity) {94 if (quantity > 0) {95 this.stockQuantity += quantity;96 System.out.println(quantity + " units added to stock. New quantity: " + this.stockQuantity);97 } else {98 System.out.println("Error: Quantity to add must be positive.");99 }100 }101102 public boolean sellProduct(int quantity) {103 if (quantity <= 0) {104 System.out.println("Error: Quantity to sell must be positive.");105 return false;106 }107108 if (quantity > stockQuantity) {109 System.out.println("Error: Not enough stock available.");110 return false;111 }112113 stockQuantity -= quantity;114 System.out.println(quantity + " units sold. Remaining stock: " + stockQuantity);115 return true;116 }117118 // Display method119 public void displayInfo() {120 System.out.println("Product: " + name);121 System.out.println("Description: " + description);122 System.out.println("Category: " + category);123 System.out.println("Price: $" + price);124 System.out.println("Price with tax: $" + getPriceWithTax());125 System.out.println("Stock Quantity: " + stockQuantity);126 System.out.println("In Stock: " + (isInStock() ? "Yes" : "No"));127 }128129 // Static methods130 public static int getTotalProducts() {131 return totalProducts;132 }133134 public static double getTaxRate() {135 return taxRate;136 }137138 public static void setTaxRate(double newRate) {139 if (newRate >= 0 && newRate <= 0.3) { // Limit between 0% and 30%140 taxRate = newRate;141 System.out.println("Tax rate updated to " + (taxRate * 100) + "%");142 } else {143 System.out.println("Error: Tax rate must be between 0% and 30%.");144 }145 }146147 // Main method for testing148 public static void main(String[] args) {149 // Creating products150 Product laptop = new Product("Laptop Pro", "High-performance laptop for professionals", 1299.99, 10, "Electronics");151 Product phone = new Product("SmartPhone X", "Latest smartphone with advanced features", 799.99, 15, "Electronics");152 Product desk = new Product("Office Desk", "Sturdy wooden desk for home office", 249.99, 5, "Furniture");153154 // Displaying total products155 System.out.println("Total products in inventory: " + Product.getTotalProducts());156 System.out.println("Current tax rate: " + (Product.getTaxRate() * 100) + "%");157158 // Displaying product information159 System.out.println("160=== Product 1 ===");161 laptop.displayInfo();162163 System.out.println("164=== Product 2 ===");165 phone.displayInfo();166167 System.out.println("168=== Product 3 ===");169 desk.displayInfo();170171 // Testing methods172 System.out.println("173=== Testing Product Operations ===");174 laptop.sellProduct(2);175 phone.addStock(5);176 desk.sellProduct(6); // Should fail, only 5 in stock177178 // Changing tax rate179 System.out.println("180=== Changing Tax Rate ===");181 Product.setTaxRate(0.095); // 9.5%182183 // Display updated information184 System.out.println("185=== Updated Product Information ===");186 laptop.displayInfo();187 }188}
Best Practices for Class and Object Design
Encapsulation
Make instance variables private and provide public getter and setter methods to control access and validation.
Single Responsibility
A class should have only one reason to change, meaning it should have only one responsibility or job.
Meaningful Names
Choose clear, descriptive names for classes, variables, and methods that indicate their purpose or behavior.
Immutability When Possible
Consider making classes immutable (variables can't change after initialization) when appropriate to prevent unexpected side effects.
Practice Exercises
- Create a
Book
class with appropriate attributes and methods for a library system. - Implement a
BankAccount
class with methods for deposit, withdrawal, and interest calculation. - Design a
Student
class with arrays to track courses and grades. - Create a
Circle
class with methods to calculate area and circumference. - Implement a
Date
class with validation and methods to compare dates.
Summary
In this tutorial, you've learned:
- The concepts of classes and objects in Java
- How to define classes and create objects
- How to use constructors to initialize objects
- The purpose and usage of the
this
keyword - Access modifiers and their role in encapsulation
- How to implement encapsulation with getters and setters
- The difference between static and instance members
- Best practices for designing classes and objects
Classes and objects form the foundation of object-oriented programming in Java. Understanding these concepts is essential for building robust and maintainable Java applications. In the next tutorials, you'll learn about inheritance, interfaces, and other advanced OOP concepts that build upon these fundamentals.
Related Tutorials
Learn how to create and use methods in Java.
Learn moreUnderstand the core concepts of OOP in Java.
Learn moreLearn about class inheritance and method overriding.
Learn more