Java interview question
Interface vs abstract class in Java: what is the difference, and where do you use each in a test framework?
Short answer
An abstract class can hold state, constructors and implemented methods, and a class extends only one. An interface defines a contract with no instance state; since Java 8 it can have default and static methods, and a class can implement many. WebDriver is an interface; BasePage is often abstract.
Answer
Both let you define behaviour that subclasses must provide, but they model different things. An abstract class is a partially built base class: it can hold fields, constructors and implemented methods, and a class can extend only one. An interface is a contract describing what a type can do: it has no instance state, a class can implement any number of them, and since Java 8 it can include default and static methods (and private helper methods since Java 9).
Side by side
| Abstract class | Interface | |
|---|---|---|
| Inheritance | extends, only one |
implements, many |
| Instance fields | yes | no (only public static final constants) |
| Constructors | yes | no |
| Method bodies | yes | default, static, private methods |
| Access modifiers on members | any | methods are public unless private |
| Models | “is-a” with shared implementation | “can-do” capability or contract |
Examples from test automation
Selenium itself is built on interfaces: WebDriver, WebElement, TakesScreenshot and JavascriptExecutor are interfaces, and ChromeDriver implements several of them. That is why you cast to TakesScreenshot to capture a screenshot: it is a separate capability.
File shot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
A typical framework uses an abstract base page for shared state and helpers:
public abstract class BasePage {
protected final WebDriver driver;
protected final WebDriverWait wait;
protected BasePage(WebDriver driver) {
this.driver = driver;
this.wait = new WebDriverWait(driver, Duration.ofSeconds(10));
}
/** Each page defines how to tell it has loaded. */
public abstract boolean isLoaded();
protected void click(By locator) {
wait.until(ExpectedConditions.elementToBeClickable(locator)).click();
}
}
public class LoginPage extends BasePage {
private final By submit = By.cssSelector("button[type=submit]");
public LoginPage(WebDriver driver) { super(driver); }
@Override public boolean isLoaded() { return driver.getTitle().contains("Sign in"); }
public void submit() { click(submit); }
}
And interfaces for interchangeable strategies:
public interface TestDataSource {
User createUser(Role role);
default User createAdmin() { return createUser(Role.ADMIN); }
}
public class ApiTestDataSource implements TestDataSource { /* calls REST endpoints */ }
public class DbTestDataSource implements TestDataSource { /* inserts rows */ }
Tests depend on TestDataSource, so switching from database seeding to API seeding does not touch them.
Choosing
- Need shared fields or constructor logic for closely related classes: abstract class.
- Defining a capability that unrelated classes may have, or something you want to mock or swap: interface.
- Be wary of deep inheritance chains (
BasePageextendsBaseComponentextendsBaseHelper…). They make page objects rigid. Composition (a page has aHeadercomponent, aWaitshelper) is often cleaner than inheritance.
What interviewers look for
- Correct rules: single versus multiple inheritance, state, constructors, default methods.
- A modern view (Java 8+ default methods), not a pre-2014 answer.
- Real framework examples such as
WebDriver/TakesScreenshotandBasePage. - Awareness of composition over inheritance.
A strong answer covers
- Single inheritance for classes, multiple interfaces
- Abstract classes can have state, constructors and concrete methods
- Interfaces define contracts; default and static methods since Java 8, private since 9
- Gives a framework example: WebDriver interface, BasePage abstract class
- Mentions composition over inheritance or when to prefer each