How to Return a Subclass Instance in an Abstract Class with Java Generics

How to return a subclass instance in an abstract class with Java generics was a question for me when I was dealing with fluent test automation projects. In this article, I will share my solution with you. When we are writing fluent test automation scripts, we need to use this keyword to return that page, screen, step etc. class’s instance in their fluent methods. I want to show this below code snippet. For example, XPage and YPage are using commonMethodForAllPages common method.

//A common step for several page/step/screen classes
public XPage commonMethodForAllPages () {
     //A common operation for all or some pages.
     System.out.println("Common Text for all pages.");
     return this;
}
//A common step for several page/step/screen classes
public YPage commonMethodForAllPages () {
     //A common operation for all or some pages.
     System.out.println("Common Text for all pages.");
     return this;
}

As you see, we are using the same method for both two classes, it is contradictory to DRY (Don’t Repeat Yourself) principle. Ok, then we need to put this common method into BasePage class and write this common method only once for all subclasses. Right? Yes, it sounds great but there is a problem here. You see, these methods are returning specific subclass instances (XPage and YPage) by using this keyword. So, how can we solve this problem? Maybe there are several techniques that exist to solve this problem but I used JAVA Generics to solve it. In the parent class (in this scenario our parent class is BasePage class), I created the below method by using JAVA Generics to return specific page class (subclass) instances by using this keyword.

public abstract class BasePage <T extends BasePage <T>> {
    //Here you have your PageBase class operations, declerations, etc...
    //....   
    //A common step for several page/step/screen classes
    public T commonMethodForAllPages () {
        //A common operation for all or some pages.
        System.out.println("Common Text for all pages.");
        return (T) this;
    }
}

Now, we can use this method in our XPage and YPage (subclasses) by extending BasePage class. No need to write this common method into our page classes. We can write only page-specific methods inside these page classes.

public class XPage extends BasePage<XPage> {
}
public class YPage extends BasePage<YPage> {
}

In this way, you will not repeat yourself and your project will be leaner. Assume that, if we have fifty-page classes which use the same fluent method which returns a specific page class instance by this keyword, we might write the same method fifty times. But in this way, we can write that common method only once and use it in all our page classes by extending BasePage class.

I hope this trick will help you in your fluent test automation projects. If you have a better solution please do not hesitate to write a comment and share it with us.

Thanks.
Onur Baskirt

2 thoughts on “How to Return a Subclass Instance in an Abstract Class with Java Generics”

  1. Hi Onur, thank you for publishing your article. I do have one question. In my case I have 2 methods in YPage, 1 that clicks a return button, and 1 that clicks a next button. The return method must return XPage, and the next button must return ZPage (think of a wizard with multiple steps and pages). Both methods use a generic clickButton method in BasePage. This clickButton method is created like you are creating the commonMethodForAllPages. Following your example, the commonMethodForAllPages only returns the type YPage as this is provided with “BasePage”. Do you know if it is possible to deal with this case, more less, following your approach?

    Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.