Polymorphism – how to check if a superclass is a subclass?

Tags: ,



This is my code:

public class WriteReviewController {
    
    private OverviewActivity overviewActivity;
    private WriteReviewActivity writeReviewActivity;
    ...
    
    public WriteReviewController(AppCompatActivity appCompatActivity) {
                if (appCompatActivity.getClass().isAssignableFrom(OverviewActivity.class))
                    this.overviewActivity = (OverviewActivity) appCompatActivity;
                else if (appCompatActivity.getClass().isAssignableFrom(WriteReviewActivity.class))
                    this.writeReviewActivity = (WriteReviewActivity) appCompatActivity;
            }
    }

This is a controller for my application. I would like this to check whether the parameter appCompatActivity is an OverviewActivity or a WriteReviewActivity. This method would be invoked for these two activities just passing as parameter this.

Is this check correct or should I use instaceof instead of isAssignableFrom?

Answer

You should use instanceof most of the cases, it is unnecessary to invoke isAssignableFrom manually. That should be done if you handle Class objects, but here you have the instances themselves.

So using instanceof your code will look the following:

public class WriteReviewController {

    private OverviewActivity overviewActivity;
    private WriteReviewActivity writeReviewActivity;
    //...

    public WriteReviewController(AppCompatActivity appCompatActivity) {
        if (appCompatActivity instanceof OverviewActivity)
            this.overviewActivity = (OverviewActivity) appCompatActivity;
        else if (appCompatActivity instanceof WriteReviewActivity)
            this.writeReviewActivity = (WriteReviewActivity) appCompatActivity;
        }
    }
}

The more clean code would be to write two constructors instead:

public class WriteReviewController {

    private OverviewActivity overviewActivity;
    private WriteReviewActivity writeReviewActivity;
    //...

    public WriteReviewController(OverviewActivity overviewActivity) {
        this.overviewActivity = overviewActivity;
    }

    public WriteReviewController(WriteReviewActivity writeReviewActivity) {
        this.writeReviewActivity = writeReviewActivity;
    }
}

But you should do that only if this is the only 2 ways you want to instantiate WriteReviewController. Your code allows passing an AppCompatActivity which is neither OverviewActivity nor WriteReviewActivity, so the behavior is not the same, I just mention this.



Source: stackoverflow