Core Java · Lesson 5
Classes and Objects
What Are Classes and Objects?
A class is a blueprint or template for creating objects, defining what data and behavior they have. An object is a specific instance of a class — you create objects from the class template. Think of a class like a cookie cutter (the design) and objects like the actual cookies (made from that cutter). Classes let you organize code logically and reuse it for creating many similar objects without duplicating code.
Creating Your First Class
A class contains attributes (data/fields) and methods (functions). Attributes describe the object's state, while methods define what it can do. Use the keyword private to hide internal details (encapsulation), and public to expose what others need. Most attributes are private; methods are often public.
public class Dog {
// Attributes (data)
private String name;
private int age;
private String breed;
// Constructor: called when you create an object
public Dog(String name, int age, String breed) {
this.name = name;
this.age = age;
this.breed = breed;
}
// Methods (behavior)
public void bark() {
System.out.println(name + " says: Woof! Woof!");
}
public void celebrate() {
age++;
System.out.println(name + " is now " + age + " years old!");
}
public void printInfo() {
System.out.println("Name: " + name + ", Breed: " + breed + ", Age: " + age);
}
}
Instantiating Objects: Creating Instances
To use a class, you instantiate it by creating an object with the new keyword. The new keyword allocates memory on the heap and calls a constructor (a special method that initializes the object). Each object is independent — changing one dog's name doesn't affect another dog.
public class DogDemo {
public static void main(String[] args) {
// Create objects using the constructor
Dog dog1 = new Dog("Buddy", 3, "Golden Retriever");
Dog dog2 = new Dog("Max", 5, "German Shepherd");
// Call methods on each object
dog1.bark(); // Output: Buddy says: Woof! Woof!
dog2.bark(); // Output: Max says: Woof! Woof!
dog1.printInfo(); // Output: Name: Buddy, Breed: Golden Retriever, Age: 3
dog1.celebrate(); // Output: Buddy is now 4 years old!
dog1.celebrate(); // Output: Buddy is now 5 years old!
}
}
Constructors: Initializing Objects
A constructor is a special method with the same name as the class. It runs when you create an object and sets initial values. You can have multiple constructors (called overloading) to support different ways of creating objects. A default constructor (no parameters) is automatically provided if you don't write one, but it's often better to write explicit constructors.
public class Person {
private String name;
private int age;
// Constructor 1: requires name and age
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Constructor 2: requires only name (age defaults to 18)
public Person(String name) {
this.name = name;
this.age = 18; // default value
}
// Constructor 3: default with no parameters
public Person() {
this.name = "Unknown";
this.age = 0;
}
public void printInfo() {
System.out.println("Person: " + name + ", Age: " + age);
}
}
class PersonDemo {
public static void main(String[] args) {
Person p1 = new Person("Alice", 30); // Uses constructor 1
Person p2 = new Person("Bob"); // Uses constructor 2
Person p3 = new Person(); // Uses constructor 3
p1.printInfo(); // Person: Alice, Age: 30
p2.printInfo(); // Person: Bob, Age: 18
p3.printInfo(); // Person: Unknown, Age: 0
}
}
Getters and Setters: Accessing Attributes
Since you should keep attributes private, use getter and setter methods to access and modify them. A getter (like getName()) returns the value; a setter (like setName(String name)) changes it. This pattern, called encapsulation, lets you add validation or logging without changing how others use your class.
public class BankAccount {
private String accountNumber;
private double balance;
public BankAccount(String accountNumber, double initialBalance) {
this.accountNumber = accountNumber;
this.balance = initialBalance;
}
// Getter for accountNumber
public String getAccountNumber() {
return accountNumber;
}
// Getter for balance
public double getBalance() {
return balance;
}
// Setter with validation
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
System.out.println("Deposited: $" + amount);
} else {
System.out.println("Deposit must be positive!");
}
}
// Setter with validation
public void withdraw(double amount) {
if (amount > 0 && amount <= balance) {
balance -= amount;
System.out.println("Withdrew: $" + amount);
} else {
System.out.println("Invalid withdrawal amount!");
}
}
}
class BankDemo {
public static void main(String[] args) {
BankAccount account = new BankAccount("123456", 1000);
System.out.println("Balance: $" + account.getBalance());
account.deposit(500); // Valid
account.withdraw(200); // Valid
account.withdraw(2000); // Invalid: exceeds balance
System.out.println("Final balance: $" + account.getBalance());
}
}
Common Mistake: Forgetting to initialize attributes in the constructor. If you create an object without setting attributes, they'll have default values (0 for numbers,
nullfor objects,falsefor booleans), which often isn't what you want. Always initialize in the constructor to ensure objects start in a valid state.
Best Practices for Classes and Objects
- Make attributes private, methods public: protects data and controls access
- Write clear constructors: ensure objects always initialize to valid states
- Use meaningful class and attribute names:
Customeris clearer thanCustorC - Keep classes focused: each class should represent one concept, not ten
- Provide getters and setters for attributes that others need to access
- Use consistent naming:
getName(),getAge()follow Java conventions - Document with comments: explain complex logic or non-obvious design choices
Real-World Example: Building a Bookstore Application
A bookstore app creates a Book class with attributes like title, author, isbn, and price. Each book is instantiated as an object. A Customer class has attributes for name, purchaseHistory, and membershipLevel. When customers browse or purchase books, the program creates Book objects, calls methods like getPrice() and addToCart(), and uses setters like applyDiscount() to adjust prices for members. By organizing code into classes representing real-world entities (books, customers, orders), the application becomes manageable and easy to extend with new features.
Quiz Check