/** * Copyright (C) 2019 Adrien Hopkins * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ package org.unitConverter.unit; /** * A unit that can be added, subtracted, multiplied or divided by another operatable unit, and raised to an integer * exponent. *

* In order to use two units in an operation, they must be part of the same unit system. In addition, in order for two * units to add or subtract, they must measure the same dimension. *

*

* It is okay for an operation to throw a {@code ClassCastException} if the operator's class cannot operate with another * class. However, all classes that implement this interface should be able to interoperate with {@code BaseUnit} and * {@code LinearUnit}. *

* * @author Adrien Hopkins * @since 2019-03-17 */ public interface OperatableUnit extends Unit { /** * Returns the quotient of this unit and another. *

* Two units can be divided if they are part of the same unit system. If {@code divisor} does not meet this * condition, an {@code IllegalArgumentException} should be thrown. *

*

* It is okay for a unit to throw a {@code ClassCastException} if it cannot operate with {@code divisor}'s class. * However, all classes that implement this interface should be able to interoperate with {@code BaseUnit} and * {@code LinearUnit}. *

* * @param divisor * unit to divide by * @return quotient * @throws IllegalArgumentException * if {@code divisor} is not compatible for division as described above * @throws NullPointerException * if {@code divisor} is null * @throws ClassCastException * if {@code divisor}'s class is incompatible with this unit's class * @since 2019-03-17 */ default OperatableUnit dividedBy(final OperatableUnit divisor) { return this.times(divisor.reciprocal()); } /** * Returns the difference of this unit and another. *

* Two units can be subtracted if they meet the following conditions: *

* If {@code subtrahend} does not meet these conditions, an {@code IllegalArgumentException} should be thrown. *

*

* It is okay for a unit to throw a {@code ClassCastException} if it cannot operate with {@code subtrahend}'s class. * However, all classes that implement this interface should be able to interoperate with {@code BaseUnit} and * {@code LinearUnit}. *

* * @param subtrahend * unit to subtract * @return difference * @throws IllegalArgumentException * if {@code subtrahend} is not compatible for subtraction as described above * @throws NullPointerException * if {@code subtrahend} is null * @throws ClassCastException * if {@code subtrahend}'s class is incompatible with this unit's class * @since 2019-03-17 */ default OperatableUnit minus(final OperatableUnit subtrahend) { return this.plus(subtrahend.negated()); } /** * @return this unit negated, i.e. -this * @since 2019-03-17 */ OperatableUnit negated(); /** * Returns the sum of this unit and another. *

* Two units can be added if they meet the following conditions: *

* If {@code addend} does not meet these conditions, an {@code IllegalArgumentException} should be thrown. *

*

* It is okay for a unit to throw a {@code ClassCastException} if it cannot operate with {@code addend}'s class. * However, all classes that implement this interface should be able to interoperate with {@code BaseUnit} and * {@code LinearUnit}. *

* * @param addend * unit to add * @return sum * @throws IllegalArgumentException * if {@code addend} is not compatible for addition as described above * @throws NullPointerException * if {@code addend} is null * @throws ClassCastException * if {@code addend}'s class is incompatible with this unit's class * @since 2019-03-17 */ OperatableUnit plus(OperatableUnit addend); /** * @return reciprocal of this unit * @since 2019-03-17 */ OperatableUnit reciprocal(); /** * Returns the product of this unit and another. *

* Two units can be multiplied if they are part of the same unit system. If {@code multiplier} does not meet this * condition, an {@code IllegalArgumentException} should be thrown. *

*

* It is okay for a unit to throw a {@code ClassCastException} if it cannot operate with {@code multiplier}'s class. * However, all classes that implement this interface should be able to interoperate with {@code BaseUnit} and * {@code LinearUnit}. *

* * @param multiplier * unit to multiply by * @return product * @throws IllegalArgumentException * if {@code multiplier} is not compatible for multiplication as described above * @throws NullPointerException * if {@code multiplier} is null * @throws ClassCastException * if {@code multiplier}'s class is incompatible with this unit's class * @since 2019-03-17 */ OperatableUnit times(OperatableUnit multiplier); /** * Returns the result of raising this unit to the exponent {@code exponent}. * * @param exponent * exponent to exponentiate by * @return result of exponentiation * @since 2019-03-17 */ OperatableUnit toExponent(int exponent); }