Define Methods in Interface Without Specifying Number of Parameters

Viewed 584

I'm trying to implement classes from the same interface but with a different number of parameters in method like the code below.

interface Shape {
    double getArea();
}

class Square implements Shape {
    @Override
    public double getArea(double side) { // error because different number of parameter
        return side;
    }
}

class Triangle implements Shape {
    @Override
    public double getArea(double height, double width) { // error because different number of parameter
        return height * width / 2;
    }
}

Is there a way in Java to define methods in the interface without constraining the number of parameters?

2 Answers

You could use the ellipsis syntax (...) and then check the number of arguments passed to the method in runtime:

interface Shape {
    double getArea(double... args);
}

class Triangle implements Shape {
    @Override
    public double getArea(double args...) {
        if (args.length != 2) {
             throw new IllegalArgumentExeption
                       ("A triangle should have a height and a width");
        }
        double height = args[0];
        double width = args[1];
        return height * width / 2;
    }
}

But this completely misses the point of having an interface and implementing its methods.

The idiomatic way to handle this in Java would be to have each shape take the appropriate arguments in its constructor and implement a no-argument getArea() method that relies on its data members:

interface Shape {
    double getArea();
}

class Triangle implements Shape {
    private height;
    private width;

    public Triangle(double height, double width) {
        this.height = height;
        this.width = width;
    }

    @Override
    public double getArea() {
        return height * width / 2;
    }
}

Unfortunately, you can not implement a method of an interface and then change its arguments (whether they may exist or no ) to whatever you like.

But luckily, there is a simple yet so efficient approach to solve what you are trying to do using each class's constructor that will take the appropriate arguments depending on the class

Here is a little example

interface Area {
    double getArea(); }


// a Triangle class that implements the Area interface
class Triangle implements Area {

    // Here as you see, each class has specific attributes, specific constructor arguments and for sure a specific method body
  
    double base,height;

    Triangle(double base, double height){
        this.base = base;
        this.height = height;
    }

    @Override
    public double getArea() {
        return ((double) 1/2) * base * height;
    }
}
//a Square class that implements the Area interface 
class Square implements Area {

    double length;

    Square(int length){
        this.length = length;
    }

    @Override
    public double getArea() {
        return length*length;
    }
}

public class Class {
    public static void main(String[] args) {

        //Creating a square object
        Square square = new Square(4);
        //Creating a triangle object
        Triangle triangle = new Triangle(12,3);

        System.out.println("Square's Area is :"+square.getArea()); // output : Square's Area is :16.0
        System.out.println("Triangle's Area is :"+triangle.getArea()); // output : Triangle's Area is :18.0

    }
}
Related