Skip to main content

Free sample lesson

Object-oriented Java for testers

Module 2, Java Foundations for Testers, from Selenium with Java Mastery. This is the full lesson, exactly as it appears in the course.

This is the most important lesson in the Java module, because the Page Object Model, the pattern your whole framework is built on, is just object-oriented Java applied to web pages. Get comfortable with classes, objects, constructors, inheritance, interfaces, and encapsulation here, and Module 06 will feel like review. We keep it concrete: every concept maps to something you will write in a real test framework.


Classes and objects

A class is a blueprint. An object is a thing built from that blueprint. The class defines what a thing has and what it can do; objects are the actual instances you work with.

public class User {
    String username;
    String password;
}

That class says "a User has a username and a password." To make an actual user, you create an object with new:

User alice = new User();
alice.username = "standard_user";
alice.password = "secret_sauce";

System.out.println(alice.username); // "standard_user"

User is the blueprint; alice is one object built from it. You can build as many as you like, each with its own values. This is exactly how a LoginPage class will become a loginPage object later.


Fields and methods

The data inside an object lives in fields, also called instance variables. The behavior lives in methods. A useful class bundles both: data plus the things you can do with it.

public class TestResult {
    String name;       // field
    boolean passed;    // field

    String summary() { // method
        return name + ": " + (passed ? "PASS" : "FAIL");
    }
}

Using it:

TestResult r = new TestResult();
r.name = "login_valid";
r.passed = true;
System.out.println(r.summary()); // "login_valid: PASS"

A method on a class can use that object's own fields directly, which is what makes objects so tidy. The summary method reaches name and passed without being handed them.


Constructors

Setting fields one by one after new is clumsy. A constructor lets you build an object fully formed in one line. It is a special method with the same name as the class and no return type:

public class User {
    String username;
    String password;

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }
}

The this keyword means "this object's own field," distinguishing it from the parameter of the same name. Now creation is one clean line:

User alice = new User("standard_user", "secret_sauce");

Page objects use constructors heavily: a LoginPage constructor takes the WebDriver and stores it so every method on the page can use the browser.


Encapsulation

Encapsulation means hiding an object's internals and exposing a clean surface. You mark fields private so outside code cannot poke at them, and you expose behavior through public methods.

public class Account {
    private int balance; // hidden from outside

    public void deposit(int amount) {
        if (amount > 0) {
            balance += amount;
        }
    }

    public int getBalance() {
        return balance;
    }
}

Outside code cannot set balance to a nonsense value directly; it must go through deposit, which enforces the rule. This is why page objects keep locators private and expose only meaningful actions like loginAs. A test should call behaviors, not reach into the page's wiring.


Inheritance

Inheritance lets one class build on another, reusing its fields and methods. The child extends the parent and adds or overrides behavior.

public class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }

    public String getTitle() {
        return driver.getTitle();
    }
}

public class LoginPage extends BasePage {
    public LoginPage(WebDriver driver) {
        super(driver); // call the parent constructor
    }

    public void loginAs(String user, String pass) {
        // uses the inherited driver field
    }
}

LoginPage gets getTitle and the driver field for free from BasePage. The super(driver) call hands the driver up to the parent constructor. This is exactly how real frameworks share common setup across every page object: put it once in a base class, inherit everywhere.


Interfaces

An interface is a contract: a list of methods a class promises to provide, with no implementation of its own. It defines what something can do without saying how.

public interface Page {
    boolean isLoaded();
}

public class LoginPage implements Page {
    public boolean isLoaded() {
        return true; // real check goes here
    }
}

LoginPage promises to provide isLoaded by implements Page. Interfaces matter in Selenium because WebDriver itself is an interface. ChromeDriver and FirefoxDriver both implement it, which is why you can write code against WebDriver and swap browsers underneath:

WebDriver driver = new ChromeDriver(); // an interface variable, concrete object

Programming to the interface, WebDriver rather than ChromeDriver, is what keeps your framework flexible.


Why OOP underpins the Page Object Model

Now you can see the whole picture. A page object is a class. Its locators are private fields, hidden by encapsulation. Its actions are public methods like loginAs. A constructor takes the WebDriver. Shared behavior lives in a base class through inheritance. The driver is an interface so browsers are swappable.

public class LoginPage extends BasePage {
    private final By username = By.id("user-name");
    private final By password = By.id("password");

    public LoginPage(WebDriver driver) {
        super(driver);
    }

    public void loginAs(String user, String pass) {
        driver.findElement(username).sendKeys(user);
        driver.findElement(password).sendKeys(pass);
    }
}

Every OOP idea in this lesson shows up in those few lines. The Page Object Model is not a new thing to learn; it is these foundations pointed at a browser.


Recap

You learned classes and objects, fields and methods, constructors with this, encapsulation with private, inheritance with extends and super, and interfaces with implements, and you saw how every one of them powers the Page Object Model. This is the conceptual core of the whole course. Next, prove it: a practice lesson of Java exercises a tester actually needs.

Keep going with Selenium with Java Mastery

14 modules and 66 lessons. Lifetime access and free updates included.

Get the full course

Or get every course in the Ultimate QA Automation Bundle