001/*
002 * Units of Measurement API
003 * Copyright (c) 2014-2019, Jean-Marie Dautelle, Werner Keil, Otavio Santana.
004 *
005 * All rights reserved.
006 *
007 * Redistribution and use in source and binary forms, with or without modification,
008 * are permitted provided that the following conditions are met:
009 *
010 * 1. Redistributions of source code must retain the above copyright notice,
011 *    this list of conditions and the following disclaimer.
012 *
013 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
014 *    and the following disclaimer in the documentation and/or other materials provided with the distribution.
015 *
016 * 3. Neither the name of JSR-385 nor the names of its contributors may be used to endorse or promote products
017 *    derived from this software without specific prior written permission.
018 *
019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
021 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
023 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
026 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030package javax.measure;
031
032/**
033 * Represents a quantitative property of a phenomenon, body, or substance, that
034 * can be quantified by measurement. {@link javax.measure.quantity.Mass Mass},
035 * time, distance, heat, and angular separation are among the familiar examples
036 * of quantitative properties.
037 * <p>
038 * <code> {@literal Unit<Mass>} pound = ... {@literal Quantity<Length>} size = ... {@literal Sensor<Temperature>}<br>
039 * thermometer = ... {@literal Vector3D<Speed>} aircraftSpeed = ... </code>
040 * </p>
041 *
042 * <h3>Arithmetic operations</h3>
043 * This interface defines some arithmetic operations between {@code Quantity}
044 * instances. All implementations shall produce <em>equivalent</em> results for
045 * the same operation applied on equivalent quantities. Two quantities are
046 * equivalent if, after conversion to the same unit of measurement, they have
047 * the same numerical value (ignoring rounding errors). For example 2000 metres
048 * is equivalent to 2 km, but 2°C is not equivalent to 2 K; it is equivalent to
049 * 275.15 K instead. Above requirement applied to addition means that 2°C + 2 K
050 * shall be equivalent to 275.15 K + 2 K.
051 *
052 * <p>All operations shall preserve the
053 * <a href="https://en.wikiversity.org/wiki/Basic_Laws_of_Algebra">basic laws
054 * of algebra</a>, in particular <b>commutativity</b> of addition and
055 * multiplication (<var>A</var> + <var>B</var> = <var>B</var> + <var>A</var>)
056 * and <b>associativity</b> of addition and multiplication (<var>A</var> +
057 * <var>B</var>) + <var>C</var> = <var>A</var> + (<var>B</var> + <var>C</var>).
058 * In order to preserve those algebra laws, this specification requires all
059 * arithmetic operations to execute <em>as is</em> all operands were converted
060 * to {@linkplain Unit#getSystemUnit() system unit} before the operation is
061 * carried out, and the result converted back to any compatible unit at
062 * implementation choice. For example 4 cm + 1 inch shall produce any result
063 * <em>equivalent</em> to 0.04 m + 0.0254 m.</p>
064 *
065 * <p>Implementations are allowed to avoid conversion to system unit if the
066 * result is guaranteed to be equivalent. This is often the case when the
067 * conversion between quantity unit and system unit is only a
068 * {@linkplain UnitConverter#isLinear() scale factor}. However this is not
069 * the case for conversions applying an offset or more complex formula.
070 * For example 2°C + 1°C = 274.15°C, not 3°C. This counter-intuitive result
071 * is essential for preserving algebra laws like associativity, and is also
072 * the expected result from a thermodynamic point of view.</p>
073 *
074 * apiNote This interface places no restrictions on the mutability of
075 *          implementations, however immutability is strongly recommended. All
076 *          implementations must be {@link Comparable}.
077 *
078 * @param <Q>
079 *            The type of the quantity.
080 *
081 * @author <a href="mailto:[email protected]">Jean-Marie Dautelle</a>
082 * @author <a href="mailto:[email protected]">Martin
083 *         Desruisseaux</a>
084 * @author <a href="mailto:[email protected]">Werner Keil</a>
085 * @author <a href="mailto:[email protected]">Otavio Santana</a>
086 * @see Unit
087 * @see <a href="http://en.wikipedia.org/wiki/Quantity">Wikipedia: Quantity</a>
088 * @see <a href="http://martinfowler.com/eaaDev/quantity.html">Martin Fowler -
089 *      Quantity</a>
090 * @version 1.11, April 16, 2019
091 * @since 1.0
092 */
093public interface Quantity<Q extends Quantity<Q>> {
094    
095   /**
096    * The scale of a {@link Quantity}, either {@code ABSOLUTE} or {@code RELATIVE}.
097    *
098    * @since 2.0
099    * @see <a href="https://en.wikipedia.org/wiki/Absolute_scale">Wikipedia: Absolute scale</a>
100    */
101    public static enum Scale {
102        ABSOLUTE, RELATIVE
103    }
104       
105    /**
106     * Returns the sum of this {@code Quantity} with the one specified.
107     * The result shall be as if this quantity and the given addend were
108     * converted to {@linkplain Unit#getSystemUnit() system unit} before
109     * to be added, and the result converted back to the unit of this
110     * quantity or any other compatible unit at implementation choice.
111     *
112     * @param addend
113     *            the {@code Quantity} to be added.
114     * @return {@code this + addend}.
115     */
116    Quantity<Q> add(Quantity<Q> addend);
117
118    /**
119     * Returns the difference between this {@code Quantity} and the one specified.
120     * The result shall be as if this quantity and the given subtrahend were
121     * converted to {@linkplain Unit#getSystemUnit() system unit} before
122     * to be subtracted, and the result converted back to the unit of this
123     * quantity or any other compatible unit at implementation choice.
124     *
125     * @param subtrahend
126     *            the {@code Quantity} to be subtracted.
127     * @return <code>this - subtrahend</code>.
128     */
129    Quantity<Q> subtract(Quantity<Q> subtrahend);
130
131    /**
132     * Returns the quotient of this {@code Quantity} divided by the {@code Quantity}
133     * specified.
134     * The result shall be as if this quantity and the given divisor were
135     * converted to {@linkplain Unit#getSystemUnit() system unit} before
136     * to be divided, and the result converted back to the unit of this
137     * quantity or any other compatible unit at implementation choice.
138     *
139     * @throws ClassCastException
140     *             if the type of an element in the specified operation is
141     *             incompatible with this quantity
142     *
143     * @param divisor
144     *            the {@code Quantity} divisor.
145     * @return <code>this / divisor</code>.
146     */
147    Quantity<?> divide(Quantity<?> divisor);
148
149    /**
150     * Returns the quotient of this {@code Quantity} divided by the {@code Number}
151     * specified.
152     * The result shall be as if this quantity was converted to
153     * {@linkplain Unit#getSystemUnit() system unit} before to be divided,
154     * and the result converted back to the unit of this quantity or any
155     * other compatible unit at implementation choice.
156     *
157     * @param divisor
158     *            the {@code Number} divisor.
159     * @return <code>this / divisor</code>.
160     */
161    Quantity<Q> divide(Number divisor);
162
163    /**
164     * Returns the product of this {@code Quantity} with the one specified.
165     * The result shall be as if this quantity and the given multiplicand were
166     * converted to {@linkplain Unit#getSystemUnit() system unit} before
167     * to be multiplied, and the result converted back to the unit of this
168     * quantity or any other compatible unit at implementation choice.
169     *
170     * @throws ClassCastException
171     *             if the type of an element in the specified operation is
172     *             incompatible with this quantity
173     *
174     * @param multiplicand
175     *            the {@code Quantity} multiplicand.
176     * @return <code>this * multiplicand</code>.
177     */
178    Quantity<?> multiply(Quantity<?> multiplicand);
179
180    /**
181     * Returns the product of this {@code Quantity} with the {@code Number} value
182     * specified.
183     * The result shall be as if this quantity was converted to
184     * {@linkplain Unit#getSystemUnit() system unit} before to be multiplied,
185     * and the result converted back to the unit of this quantity or any
186     * other compatible unit at implementation choice.
187     *
188     * @param multiplicand
189     *            the {@code Number} multiplicand.
190     * @return <code>this * multiplicand</code>.
191     */
192    Quantity<Q> multiply(Number multiplicand);
193
194    /**
195     * Returns this {@code Quantity} converted into another (compatible)
196     * {@code Unit}.
197     *
198     * @param unit
199     *            the {@code Unit unit} in which the returned quantity is stated.
200     * @return this quantity or a new quantity equivalent to this quantity stated in the specified unit.
201     * @throws ArithmeticException
202     *             if the result is inexact and the quotient has a non-terminating decimal expansion.
203     */
204    Quantity<Q> to(Unit<Q> unit);
205
206    /**
207     * Returns a {@code Quantity} that is the multiplicative inverse of this
208     * {@code Quantity}, having reciprocal value and reciprocal unit as given by
209     * {@code this.getUnit().inverse()}.
210     *
211     * @return reciprocal {@code Quantity}
212     * @see <a href=
213     *      "https://en.wikipedia.org/wiki/Multiplicative_inverse">Wikipedia:
214     *      Multiplicative inverse</a>
215     */
216    Quantity<?> inverse();
217
218    /**
219     * Returns a {@code Quantity} whose value is {@code (-this.getValue())}.
220     *
221     * @return {@code -this}.
222     */
223    Quantity<Q> negate();
224
225    /**
226     * Casts this quantity to a parameterized unit of specified nature or throw a
227     * <code>ClassCastException</code> if the dimension of the specified quantity
228     * and this measure unit's dimension do not match. For example:
229     * <p>
230     * <code>
231     *     {@literal Quantity<Length>} length = Quantities.getQuantity("2 km").asType(Length.class);
232     * </code> or <code>
233     *     {@literal Quantity<Speed>} C = length.multiply(299792458).divide(second).asType(Speed.class);
234     * </code>
235     * </p>
236     *
237     * @param <T>
238     *            The type of the quantity.
239     * @param type
240     *            the quantity class identifying the nature of the quantity.
241     * @return this quantity parameterized with the specified type.
242     * @throws ClassCastException
243     *             if the dimension of this unit is different from the specified
244     *             quantity dimension.
245     * @throws UnsupportedOperationException
246     *             if the specified quantity class does not have a SI unit for the
247     *             quantity.
248     * @see Unit#asType(Class)
249     */
250    <T extends Quantity<T>> Quantity<T> asType(Class<T> type) throws ClassCastException;
251
252    /**
253     * Returns the value of this {@code Quantity}.
254     *
255     * @return a value.
256     */
257    Number getValue();
258
259    /**
260     * Returns the unit of this {@code Quantity}.
261     *
262     * @return the unit (shall not be {@code null}).
263     */
264    Unit<Q> getUnit();
265    
266    /**
267     * Convenient method equivalent to {@link #to(javax.measure.Unit)
268     * to(getUnit().toSystemUnit())}.
269     *
270     * @return this quantity or a new quantity equivalent to this quantity stated in
271     *         SI units.
272     * @throws ArithmeticException
273     *             if the result is inexact and the quotient has a non-terminating
274     *             decimal expansion.
275     */
276    default Quantity<Q> toSystemUnit() {
277        return to(getUnit().getSystemUnit());
278    }
279      
280    /**
281     * Returns the {@code Scale} of this {@code Quantity}, if it's absolute or relative.
282     *
283     * @return the scale, if it's an absolute or relative quantity.
284     * @since 2.0
285     
286     * @see <a href="https://en.wikipedia.org/wiki/Absolute_scale">Wikipedia: Absolute scale</a>
287     */
288    Scale getScale();
289}