Home > Software engineering >  How do I implement two interface in the same class depending on the condition without using any impo
How do I implement two interface in the same class depending on the condition without using any impo

Time:10-03

I want to know how do I use 1 interface at one time when there is two interface in one class. For example, when Cube is not fixed() I can change it's length via interface properties. However, once it is fixed it only can access interface calculate which is volume() or area().

public interface properties <T> {
    T size(int length);
    T fixed();
}

public interface calculate{
    int volume();
    int area();
}

public class Cube implements properties, calculate{
    private final int length;

    public Cube(int length){this.length = length;}

}

CodePudding user response:

Factory of shape as mentioned would be my preference.

However, if you really want to control whenever you can start to use the computation methods -> I would suggest to throw an exception if the shape is not fixed, and manage that by inheritance, like

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public abstract class Calculate {

    private boolean fixed = false;

    protected abstract int computeVolume();

    protected abstract int computeArea();

    public int volume() {
        if (!fixed) {
            throw new UnsupportedOperationException("not yet fixed!");
        }
        return computeVolume();
    }

    public int area() {
        if (!fixed) {
            throw new UnsupportedOperationException("not yet fixed!");
        }
        return computeArea();
    }

}
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Cube extends Calculate {

    private int length;

    @Override
    protected int computeVolume() {
        return length * length * length;
    }

    @Override
    protected int computeArea() {
        return 6 * (length * length);
    }
}

Here are some unit tests to validate:

import static org.junit.Assert.*;

import org.junit.Test;

public class CubeTest {

    @Test
    public void testCubeWhenFixed() {
        Cube cube = new Cube();
        cube.setLength(4);
        cube.setFixed(true);

        int vol = cube.volume();
        assertEquals(64, vol);
    }

    @Test (expected = UnsupportedOperationException.class)
    public void testCubeWhenNotFixed() {
        Cube cube = new Cube();
        cube.setLength(4);

        int vol = cube.volume();
    }

}

CodePudding user response:

If you don't represent the fixedness of a Cube at the type level, your code will be much more difficult to maintain.

I would have a mutable CubeBuilder which just has:

class CubeBuilder {
  private int length;
  public void setLength(int newLength) { this.length = newLength; }
  public Cube build() { return new Cube(length); }
}

and then an immutable Cube which has volume and area.

Otherwise, as you work on your program, you will never be quite sure which methods it's OK to pass a non-fixed Cube to, and whether a given Cube reference is fixed or non-fixed.

  • Related