Instance methods are functions that belong to a specific object (instance) of a class. Unlike static methods, instance methods can access and modify the object's fields (instance variables) and call other instance methods of the same class.
Think of instance methods as actions that an object can perform or information that an object can provide about itself.
- Belong to specific objects (instances)
- Can access instance fields and other instance methods
- Called on objects:
myObject.methodName() - Each object has its own copy of the data
- Belong to the class itself, not to any specific object
- Cannot access instance fields or methods directly
- Called on the class:
ClassName.methodName() - Shared by all instances of the class
class Person {
String name; // Instance field
// Instance method - operates on this specific Person object
public String introduce() {
return "Hello, I'm " + name; // Can access instance field
}
// Static method - belongs to the Person class
public static String getSpecies() {
return "Homo sapiens"; // Cannot access instance fields
}
}
// Usage:
Person person = new Person();
person.name = "Alice";
String greeting = person.introduce(); // Instance method call
String species = Person.getSpecies(); // Static method callpublic returnType methodName(parameterType parameterName) {
// Method body
return someValue; // if return type is not void
}public- accessible from anywhereprivate- accessible only within the same classprotected- accessible within package and subclasses- (no modifier) - package-private
void- method doesn't return anythingint,double,String, etc. - method returns a value of that type- Custom class types - method returns an object
- Should be a verb describing what the method does
- Use camelCase:
calculateTotal(),getName(),isValid()
- Input values the method needs to do its work
- Can have zero, one, or multiple parameters
- Each parameter has a type and name
Return information about the object's state:
class BankAccount {
private double balance;
private String accountNumber;
public double getBalance() {
return balance; // Return current balance
}
public String getAccountNumber() {
return accountNumber; // Return account number
}
public boolean hasInsufficientFunds(double amount) {
return balance < amount; // Return calculated result
}
}Modify the object's state:
class BankAccount {
private double balance;
public void deposit(double amount) {
if (amount > 0) {
balance += amount; // Modify instance field
}
}
public void withdraw(double amount) {
if (amount > 0 && balance >= amount) {
balance -= amount; // Modify instance field
}
}
}Perform computations using object data:
class Rectangle {
private double length;
private double width;
public double calculateArea() {
return length * width; // Calculate using instance fields
}
public double calculatePerimeter() {
return 2 * (length + width); // Calculate using instance fields
}
}Check if object state or parameters are valid:
class Student {
private ArrayList<Double> grades;
public boolean addGrade(double grade) {
if (grade >= 0 && grade <= 100) {
grades.add(grade);
return true; // Valid grade added
}
return false; // Invalid grade rejected
}
public boolean isPassingGrade() {
return calculateAverage() >= 60.0;
}
}Perform helper operations for the object:
class TextProcessor {
private String text;
public String reverse() {
StringBuilder sb = new StringBuilder(text);
return sb.reverse().toString(); // Return processed data
}
public int getWordCount() {
if (text == null || text.trim().isEmpty()) {
return 0;
}
return text.trim().split("\\s+").length;
}
}Each method should do one thing well:
// Good - each method has one clear purpose
public double calculateTotal() { ... }
public void addItem(String item) { ... }
public boolean isEmpty() { ... }
// Poor - method does too many things
public void processOrderAndSendEmailAndUpdateInventory() { ... }Method names should clearly describe what they do:
// Good method names
public double calculateInterest()
public boolean isValidEmail()
public void removeExpiredItems()
// Poor method names
public double doStuff()
public boolean check()
public void process()Return what callers need:
// Return boolean for yes/no questions
public boolean isEmpty()
public boolean isValid()
// Return the actual value for data access
public double getBalance()
public String getName()
// Return boolean for operations that can fail
public boolean withdraw(double amount)
public boolean addItem(String item)Check parameters to prevent errors:
public void deposit(double amount) {
if (amount <= 0) {
return; // or throw exception
}
balance += amount;
}
public void setGrade(double grade) {
if (grade < 0 || grade > 100) {
return; // Invalid grade
}
this.grade = grade;
}this refers to the current object instance:
class Person {
private String name;
public void setName(String name) {
this.name = name; // this.name = instance field, name = parameter
}
}class Calculator {
private double result;
public void addAndDisplay(double value) {
add(value); // Calls add() on this object
this.display(); // Explicitly calls display() on this object
}
public void add(double value) {
result += value;
}
public void display() {
System.out.println("Result: " + result);
}
}class StringBuilder {
public StringBuilder append(String str) {
// ... append logic ...
return this; // Allow method chaining
}
}
// Usage: sb.append("Hello").append(" ").append("World");class Person {
private String name;
private int age;
private String email;
public Person setName(String name) {
this.name = name;
return this;
}
public Person setAge(int age) {
this.age = age;
return this;
}
public Person setEmail(String email) {
this.email = email;
return this;
}
}
// Usage: Person person = new Person().setName("Alice").setAge(25).setEmail("alice@example.com");class Counter {
private int count;
private boolean isActive;
public void start() {
isActive = true;
count = 0;
}
public void increment() {
if (isActive) {
count++;
}
}
public void stop() {
isActive = false;
}
public boolean isRunning() {
return isActive;
}
}class Statistics {
private ArrayList<Double> data;
public void addValue(double value) {
data.add(value);
}
public double calculateMean() {
return data.stream().mapToDouble(Double::doubleValue).average().orElse(0.0);
}
public double findMax() {
return data.stream().mapToDouble(Double::doubleValue).max().orElse(0.0);
}
public void reset() {
data.clear();
}
}You can have multiple methods with the same name but different parameters:
class Calculator {
public double add(double a, double b) {
return a + b;
}
public double add(double a, double b, double c) {
return a + b + c;
}
public int add(int a, int b) {
return a + b;
}
}// Good - focused on one task
public double calculateTax(double amount) {
return amount * TAX_RATE;
}
// Poor - doing too many things
public double calculateTaxAndUpdateRecordsAndSendNotification(double amount) {
// Too much responsibility
}// Good
public boolean isEligibleForDiscount()
public void removeExpiredItems()
public double calculateMonthlyPayment()
// Poor
public boolean check()
public void remove()
public double calc()public void setAge(int age) {
if (age < 0 || age > 150) {
throw new IllegalArgumentException("Invalid age: " + age);
}
this.age = age;
}// Good - return success/failure for operations
public boolean withdraw(double amount) {
if (balance >= amount) {
balance -= amount;
return true;
}
return false;
}
// Good - return computed values
public double calculateInterest() {
return balance * interestRate;
}class Order {
private ArrayList<Item> items;
private double taxRate;
public double calculateTotal() {
return calculateSubtotal() + calculateTax();
}
private double calculateSubtotal() {
return items.stream().mapToDouble(Item::getPrice).sum();
}
private double calculateTax() {
return calculateSubtotal() * taxRate;
}
}// Poor - method does too much
public void processOrder() {
// 50+ lines of code doing many different things
}
// Better - break into smaller methods
public void processOrder() {
validateOrder();
calculateTotals();
updateInventory();
sendConfirmation();
}// Poor - void method when return value would be useful
public void withdraw(double amount) {
if (balance >= amount) {
balance -= amount;
}
// Caller doesn't know if withdrawal succeeded
}
// Better - return success/failure
public boolean withdraw(double amount) {
if (balance >= amount) {
balance -= amount;
return true;
}
return false;
}// Poor - method depends on external state
public void processUserInput() {
String input = scanner.nextLine(); // External dependency
// ...
}
// Better - pass dependencies as parameters
public void processUserInput(String input) {
// ...
}Instance methods model real-world actions and calculations:
deposit(),withdraw(),transfer()calculateInterest(),checkBalance()
addToCart(),removeFromCart()calculateTotal(),applyDiscount()
move(),attack(),heal()levelUp(),gainExperience()
toUpperCase(),reverse(),getWordCount()contains(),replace()
When you call an instance method:
- Object Context: The method executes in the context of a specific object
- Field Access: The method can read and modify the object's fields
- Method Calls: The method can call other instance methods on the same object
- Return Value: The method can return information or indicate success/failure
BankAccount account = new BankAccount("123-456"); // Create object
account.deposit(100.0); // Call instance method on 'account' object
double balance = account.getBalance(); // Method returns object's dataRemember: Instance methods are the primary way objects interact with the world and provide functionality to the programs that use them!