A class is a blueprint that describes data (fields) and behaviour (methods). An object is one concrete thing built from that blueprint with new. A LoginPage class describes what every login page has and can do; new LoginPage(driver) creates the object your test actually uses. Classes and objects are the foundation of every Java framework, so it's worth getting them exactly right.

Defining a Class

public class User {
    // fields: the object's state
    private String name;
    private String role;
    private boolean active = true;

    // constructor: runs when an object is created
    public User(String name, String role) {
        this.name = name;
        this.role = role;
    }

    // methods: the object's behaviour
    public String getName() { return name; }
    public boolean isAdmin() { return "admin".equals(role); }
    public void deactivate() { active = false; }
}

A class usually contains fields, constructors and methods. Fields are normally private and reached through methods, which is encapsulation: the class controls how its data changes.

Advertisement

Creating and Using Objects

User asha = new User("Asha", "admin");
User ravi = new User("Ravi", "qa");

System.out.println(asha.getName());   // Asha
System.out.println(ravi.isAdmin());   // false

new allocates the object on the heap, runs the constructor and returns a reference to it. The variable asha holds that reference, not the object itself.

References: Two Variables, One Object

User a = new User("Asha", "admin");
User b = a;            // copies the reference, not the object
b.deactivate();        // a sees the change too: same object
User c = null;         // refers to no object
c.getName();           // NullPointerException

This explains several everyday bugs: changing shared test data in one test affects another, and calling a method on a variable that was never assigned throws NullPointerException.

Constructors

  • A constructor has the class name and no return type.
  • If you write none, Java provides a no-argument default constructor. Once you write any constructor, that default disappears.
  • Constructors can be overloaded, and one can call another with this(...); a child class calls its parent's with super(...). See access modifiers and super.

Instance vs static Members

Instance fields belong to each object: every User has its own name. static fields and methods belong to the class and are shared:

public class ConfigReader {
    private static final Properties props = load();   // one copy for the whole program
    public static String get(String key) { return props.getProperty(key); }
    private static Properties load() { /* read config.properties */ return new Properties(); }
}

String url = ConfigReader.get("baseUrl");   // no object needed

Use static for stateless utilities and constants. Don't make a WebDriver a plain static field in a framework that runs in parallel; every thread would share one browser.

The this Keyword

this refers to the current object. It's needed when a parameter has the same name as a field (this.name = name) and lets a method return the object itself for method chaining.

A Class in a Real Framework: the Page Object

public class LoginPage {
    private final WebDriver driver;
    private final By username = By.id("user-name");
    private final By password = By.id("password");
    private final By loginBtn = By.id("login-button");

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

    public InventoryPage loginAs(String user, String pass) {
        driver.findElement(username).sendKeys(user);
        driver.findElement(password).sendKeys(pass);
        driver.findElement(loginBtn).click();
        return new InventoryPage(driver);
    }
}

// in a test
InventoryPage inventory = new LoginPage(driver).loginAs("standard_user", "secret_sauce");

Fields hold the driver and locators, the constructor receives the driver, and methods describe what a user can do. That's the Page Object Model in one class.

toString, equals and hashCode

Every class inherits these from Object. Override toString() so objects print usefully in logs and reports, and override equals() and hashCode() together when two objects with the same data should count as equal, for example when comparing an expected User with one returned by an API.

Records for Test Data (Java 16+)

A record is a compact class for immutable data. Java generates the constructor, accessors, equals, hashCode and toString:

public record LoginData(String username, String password, String expectedMessage) {}

LoginData locked = new LoginData("locked_out_user", "secret_sauce", "Sorry, this user has been locked out.");
System.out.println(locked.username());

Records are ideal for DataProvider rows and API payloads that don't change after creation.

FAQs

What is the difference between a class and an object in Java?

A class is the blueprint that defines fields and methods; an object is an instance of that class created with new, with its own field values. One class can produce many objects.

How many ways can you create an object in Java?

Most commonly with new. Others include reflection (Constructor.newInstance()), clone(), deserialization, and factory methods such as List.of() that call a constructor for you.

What is the default value of an object reference?

null for fields. Local variables have no default and must be assigned before use, or the code won't compile.

Can a class have more than one constructor?

Yes. Constructors can be overloaded with different parameter lists, and one can call another with this(...) as its first statement.