001/*
002 * Units of Measurement API
003 * Copyright (c) 2014-2018, 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.3, August 2, 2018
091 * @since 1.0
092 */
093public interface Quantity<Q extends Quantity<Q>> {
094
095        /**
096         * Returns the sum of this {@code Quantity} with the one specified.
097         * The result shall be as if this quantity and the given addend were
098         * converted to {@linkplain Unit#getSystemUnit() system unit} before
099         * to be added, and the result converted back to the unit of this
100         * quantity or any other compatible unit at implementation choice.
101         *
102         * @param addend
103         *            the {@code Quantity} to be added.
104         * @return {@code this + addend}.
105         */
106        Quantity<Q> add(Quantity<Q> addend);
107
108        /**
109         * Returns the difference between this {@code Quantity} and the one specified.
110         * The result shall be as if this quantity and the given subtrahend were
111         * converted to {@linkplain Unit#getSystemUnit() system unit} before
112         * to be subtracted, and the result converted back to the unit of this
113         * quantity or any other compatible unit at implementation choice.
114         *
115         * @param subtrahend
116         *            the {@code Quantity} to be subtracted.
117         * @return <code>this - subtrahend</code>.
118         */
119        Quantity<Q> subtract(Quantity<Q> subtrahend);
120
121        /**
122         * Returns the product of this {@code Quantity} divided by the {@code Quantity}
123         * specified.
124         * The result shall be as if this quantity and the given divisor were
125         * converted to {@linkplain Unit#getSystemUnit() system unit} before
126         * to be divided, and the result converted back to the unit of this
127         * quantity or any other compatible unit at implementation choice.
128         *
129         * @throws ClassCastException
130         *             if the type of an element in the specified operation is
131         *             incompatible with this quantity
132         *             (<a href="#optional-restrictions">optional</a>)
133         *
134         * @param divisor
135         *            the {@code Quantity} divisor.
136         * @return <code>this / divisor</code>.
137         */
138        Quantity<?> divide(Quantity<?> divisor);
139
140        /**
141         * Returns the product of this {@code Quantity} divided by the {@code Number}
142         * specified.
143         * The result shall be as if this quantity was converted to
144         * {@linkplain Unit#getSystemUnit() system unit} before to be divided,
145         * and the result converted back to the unit of this quantity or any
146         * other compatible unit at implementation choice.
147         *
148         * @param divisor
149         *            the {@code Number} divisor.
150         * @return <code>this / divisor</code>.
151         */
152        Quantity<Q> divide(Number divisor);
153
154        /**
155         * Returns the product of this {@code Quantity} with the one specified.
156         * The result shall be as if this quantity and the given multiplicand were
157         * converted to {@linkplain Unit#getSystemUnit() system unit} before
158         * to be multiplied, and the result converted back to the unit of this
159         * quantity or any other compatible unit at implementation choice.
160         *
161         * @throws ClassCastException
162         *             if the type of an element in the specified operation is
163         *             incompatible with this quantity
164         *             (<a href="#optional-restrictions">optional</a>)
165         *
166         * @param multiplicand
167         *            the {@code Quantity} multiplicand.
168         * @return <code>this * multiplicand</code>.
169         */
170        Quantity<?> multiply(Quantity<?> multiplicand);
171
172        /**
173         * Returns the product of this {@code Quantity} with the {@code Number} value
174         * specified.
175         * The result shall be as if this quantity was converted to
176         * {@linkplain Unit#getSystemUnit() system unit} before to be multiplied,
177         * and the result converted back to the unit of this quantity or any
178         * other compatible unit at implementation choice.
179         *
180         * @param multiplicand
181         *            the {@code Number} multiplicand.
182         * @return <code>this * multiplicand</code>.
183         */
184        Quantity<Q> multiply(Number multiplicand);
185
186        /**
187         * Returns this {@code Quantity} converted into another (compatible)
188         * {@code Unit}.
189         *
190         * @param unit
191         *            the {@code Unit} to convert to.
192         * @return the converted result.
193         */
194        Quantity<Q> to(Unit<Q> unit);
195
196        /**
197         * Returns a {@code Quantity} that is the multiplicative inverse of this
198         * {@code Quantity}, having reciprocal value and reciprocal unit as given by
199         * {@code this.getUnit().inverse()}.
200         *
201         * @return reciprocal {@code Quantity}
202         * @see <a href=
203         *      "https://en.wikipedia.org/wiki/Multiplicative_inverse">Wikipedia:
204         *      Multiplicative inverse</a>
205         */
206        Quantity<?> inverse();
207
208        /**
209     * Returns a {@code Quantity} whose value is {@code (-this.getValue())}.
210     *
211     * @return {@code -this}.
212     */
213        Quantity<Q> negate();
214
215        /**
216         * Casts this quantity to a parameterized unit of specified nature or throw a
217         * <code>ClassCastException</code> if the dimension of the specified quantity
218         * and this measure unit's dimension do not match. For example:
219         * <p>
220         * <code>
221         *     {@literal Quantity<Length>} length = Quantities.getQuantity("2 km").asType(Length.class);
222         * </code> or <code>
223         *     {@literal Quantity<Speed>} C = length.multiply(299792458).divide(second).asType(Speed.class);
224         * </code>
225         * </p>
226         *
227         * @param <T>
228         *            The type of the quantity.
229         * @param type
230         *            the quantity class identifying the nature of the quantity.
231         * @return this quantity parameterized with the specified type.
232         * @throws ClassCastException
233         *             if the dimension of this unit is different from the specified
234         *             quantity dimension.
235         * @throws UnsupportedOperationException
236         *             if the specified quantity class does not have a SI unit for the
237         *             quantity.
238         * @see Unit#asType(Class)
239         */
240        <T extends Quantity<T>> Quantity<T> asType(Class<T> type) throws ClassCastException;
241
242        /**
243         * Returns the value of this {@code Quantity}.
244         *
245         * @return a value.
246         */
247        Number getValue();
248
249        /**
250         * Returns the unit of this {@code Quantity}.
251         *
252         * @return the unit (shall not be {@code null}).
253         */
254        Unit<Q> getUnit();
255
256        /**
257         * Convenient method equivalent to {@link #to(javax.measure.Unit)
258         * to(getUnit().toSystemUnit())}.
259         *
260         * @return this quantity or a new quantity equivalent to this quantity stated in
261         *         SI units.
262         * @throws ArithmeticException
263         *             if the result is inexact and the quotient has a non-terminating
264         *             decimal expansion.
265         */
266        default Quantity<Q> toSystemUnit() {
267                return to(getUnit().getSystemUnit());
268        }
269}