Lesson 1
Revisiting Java Classes and Object-Oriented Programming
Revisiting Java Classes and Object-Oriented Programming

Greetings! Today, we're exploring Java classes, the core building block of Object-Oriented Programming (OOP) in Java. Classes play a pivotal role in structuring code to model real-world entities and behaviors. Through hands-on examples, we'll delve into the fundamental concepts of Java classes, including their structure, methods, and encapsulation. This session aims to enhance your understanding of how classes facilitate better code organization and reusability.

Java Classes Refresher

Let's begin with a refresher on Java classes. Essential to OOP, Java classes bundle relevant data and functions into compact units called objects. Consider a video game character, which is a typical example of a class instance, with specific fields (such as health and strength) and methods (such as attack).

Java
1class GameCharacter { 2 // Fields 3 private String name; 4 private int health; 5 private int strength; 6 7 // Constructor 8 public GameCharacter(String name, int health, int strength) { 9 this.name = name; 10 this.health = health; 11 this.strength = strength; 12 } 13 14 // Method 15 public void attack(GameCharacter otherCharacter) { 16 otherCharacter.health -= this.strength; 17 } 18 19 // Getter methods 20 public String getName() { 21 return name; 22 } 23 24 public int getHealth() { 25 return health; 26 } 27 28 public int getStrength() { 29 return strength; 30 } 31} 32 33class Solution { 34 public static void main(String[] args) { 35 // Example usage 36 GameCharacter character1 = new GameCharacter("Hero", 100, 20); 37 GameCharacter character2 = new GameCharacter("Villain", 80, 15); 38 39 System.out.println(character2.getHealth()); // Prints: 80 40 character1.attack(character2); // character1 attacks character2 41 System.out.println(character2.getHealth()); // Prints: 60 42 } 43}

In the code above, the GameCharacter class has fields name, health, and strength. Each of these fields is accessed via getter methods, such as getHealth(), which provide a way to access these private fields from outside the class while maintaining encapsulation.

Java classes facilitate the grouping of associated code elements, simplifying their management. Now, let's go through this example step-by-step to better understand how it functions.

Structure of a Java Class

A Java class serves as a blueprint for creating objects, consisting of fields and methods. Fields represent data relevant to a class instance, while methods define actions or functions that manipulate this data. Each class includes a constructor, which is used to initialize the class's fields.

In Java, the this keyword represents the current class instance. It allows each object to keep track of its own state and activities. When a new class instance is created, parameters are passed to the constructor, as demonstrated in GameCharacter character = new GameCharacter("Hero", 100, 20);.

Java
1class GameCharacter { 2 // Fields 3 private String name; 4 private int health; 5 private int strength; 6 7 // Constructor 8 public GameCharacter(String name, int health, int strength) { 9 this.name = name; 10 this.health = health; 11 this.strength = strength; 12 } 13 14 // Getter methods 15 public String getName() { 16 return name; 17 } 18 19 public int getHealth() { 20 return health; 21 } 22 23 public int getStrength() { 24 return strength; 25 } 26}
Class Encapsulation

Encapsulation in Java is achieved using access modifiers and methods. Fields in Java classes are typically private to prevent direct access from outside the class, and methods such as getters and setters are used for accessing and modifying these fields.

In our GameCharacter class, name, health, and strength are private fields accessed via public getter methods.

Java
1class GameCharacter { 2 // Fields 3 private String name; 4 private int health; 5 private int strength; 6 7 // Constructor 8 public GameCharacter(String name, int health, int strength) { 9 this.name = name; 10 this.health = health; 11 this.strength = strength; 12 } 13 14 // Getter methods 15 public String getName() { 16 return name; 17 } 18 19 public int getHealth() { 20 return health; 21 } 22 23 public int getStrength() { 24 return strength; 25 } 26}

These methods provide a controlled way to access and interact with an object's fields, preserving the principle of encapsulation.

Class Methods

A class can contain methods that define actions or behaviors. In the GameCharacter class, the attack method is an example of how one object can interact with another by modifying its state.

Java
1class GameCharacter { 2 // Fields 3 private String name; 4 private int health; 5 private int strength; 6 7 // Constructor 8 public GameCharacter(String name, int health, int strength) { 9 this.name = name; 10 this.health = health; 11 this.strength = strength; 12 } 13 14 // Method 15 public void attack(GameCharacter otherCharacter) { 16 otherCharacter.health -= this.strength; 17 } 18 19 // Getter methods... 20}

The attack method directly modifies the health field of another GameCharacter instance, illustrating inter-object behavior.

Examples of Java Classes, Methods, and Encapsulation

To further understand Java classes, let's explore another example with a BankAccount class. This example demonstrates modeling real-world entities using object-oriented programming by defining fields like the account holder's name and balance, and methods for depositing and withdrawing money.

Java
1class BankAccount { 2 // Fields 3 private String holderName; 4 private double balance; 5 6 // Constructor with a default balance of 0 7 public BankAccount(String holderName, double balance) { 8 this.holderName = holderName; 9 this.balance = balance; 10 } 11 12 // Method to deposit money 13 public void deposit(double amount) { 14 if (amount > 0) { 15 this.balance += amount; 16 System.out.println(amount + " deposited. New balance: " + this.balance); 17 } else { 18 System.out.println("Deposit amount must be positive."); 19 } 20 } 21 22 // Method to withdraw money 23 public void withdraw(double amount) { 24 if (0 < amount && amount <= this.balance) { 25 this.balance -= amount; 26 System.out.println(amount + " withdrawn. Remaining balance: " + this.balance); 27 } else { 28 System.out.println("Insufficient balance for the withdrawal or amount is not positive."); 29 } 30 } 31 32 // Getter methods 33 public String getHolderName() { 34 return holderName; 35 } 36 37 public double getBalance() { 38 return balance; 39 } 40} 41 42class Solution { 43 public static void main(String[] args) { 44 BankAccount account = new BankAccount("Alex", 1000); // An account with an initial balance of 1000 45 46 account.deposit(500); // Deposit money 47 // Output: 500 deposited. New balance: 1500 48 49 account.withdraw(200); // Withdraw money 50 // Output: 200 withdrawn. Remaining balance: 1300 51 52 System.out.println("Final balance in " + account.getHolderName() + "'s account: " + account.getBalance()); 53 // Output: Final balance in Alex's account: 1300 54 } 55}

In the BankAccount class, the fields holderName and balance are private, with public getter methods to retrieve these values. This organization emphasizes encapsulation and demonstrates how Java classes encapsulate data and behavior.

Lesson Summary

Great work exploring Java classes, their methods, and encapsulation principles. Java classes help in organizing your code, improving its readability and manageability. Now, test your understanding with practical exercises to solidify your newly acquired knowledge. Happy coding!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.