001/*
002 * Units of Measurement API
003 * Copyright (c) 2014-2015, Jean-Marie Dautelle, Werner Keil, V2COM.
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-363 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 * <p>
034 * Represents a quantitative property of a phenomenon, body, or substance, that can be quantified by measurement. {@link javax.measure.quantity.Mass Mass}, time,
035 * distance, heat, and angular separation are among the familiar examples of
036 * quantitative properties.
037 * </p>
038 *
039 * <code> Unit<Mass> pound = ... Quantity<Length> size = ... Sensor<Temperature><br>
040 * thermometer = ... Vector3D<Speed> aircraftSpeed = ... </code>
041 * </p>
042 * 
043 * @apiNote
044 * This interface places no restrictions on the mutability of implementations,
045 * however immutability is strongly recommended.
046 * All implementations must be {@link Comparable}.
047 *
048 * @param <Q>
049 *            The type of the quantity.
050 *
051 * @author <a href="mailto:[email protected]">Jean-Marie Dautelle</a>
052 * @author <a href="mailto:[email protected]">Martin
053 *         Desruisseaux</a>
054 * @author <a href="mailto:[email protected]">Werner Keil</a>
055 * @author <a href="mailto:[email protected]">Otavio Santana</a>
056 * @see <a href="http://en.wikipedia.org/wiki/Quantity">Wikipedia: Quantity</a>
057 * @see <a href="http://martinfowler.com/eaaDev/quantity.html"> Martin Fowler -
058 *      Quantity</a>
059 * @see <a href="http://en.wikipedia.org/wiki/Conversion_of_units">Wikipedia:
060 *      Conversion of units</a>
061 * @version 0.25, Date: 2014-12-07
062 */
063public interface Quantity<Q extends Quantity<Q>> {
064
065        /**
066         * Returns the sum of this {@code Quantity} with the one specified.
067         *
068         * @param augend
069         *            the {@code Quantity} to be added.
070         * @return {@code this + augend}.
071         */
072        Quantity<Q> add(Quantity<Q> augend);
073
074        /**
075         * Returns the difference between this {@code Quantity} and the one
076         * specified.
077         *
078         * @param subtrahend
079         *            the {@code Quantity} to be subtracted.
080         * @return <code>this - that</code>.
081         */
082        Quantity<Q> subtract(Quantity<Q> subtrahend);
083
084        /**
085         * Returns the product of this {@code Quantity} divided by the {@code Quantity}
086         * specified.
087         *
088         * @throws ClassCastException if the type of an element
089         *         in the specified operation is incompatible with this
090         *         quantity
091         *         (<a href="#optional-restrictions">optional</a>)
092         *
093         * @param divisor
094         *            the {@code Quantity} divisor.
095         * @return <code>this / that</code>.
096         */
097        Quantity<?> divide(Quantity<?> divisor);
098
099        /**
100         * Returns the product of this {@code Quantity} divided by the {@code Number}
101         * specified.
102         *
103         * @param divisor
104         *            the {@code Number} divisor.
105         * @return <code>this / that</code>.
106         */
107        Quantity<Q> divide(Number divisor);
108
109        /**
110         * Returns the product of this {@code Quantity} with the one specified.
111         *
112         * @throws ClassCastException if the type of an element
113     *         in the specified operation is incompatible with this
114     *         quantity
115     *         (<a href="#optional-restrictions">optional</a>)
116         *
117         * @param that
118         *            the {@code Quantity} multiplier.
119         * @return <code>this * multiplier</code>.
120         */
121        Quantity<?> multiply(Quantity<?> multiplier);
122        
123        /**
124         * Returns the product of this {@code Quantity} with the {@code Number} value
125         * specified.
126         *
127         * @param that
128         *            the {@code Number} multiplier.
129         * @return <code>this * multiplier</code>.
130         */
131        Quantity<Q> multiply(Number multiplier);
132
133        /**
134         * Returns a {@code Quantity} whose unit is {@code unit.inverse()}.
135         *
136         * @return {@code Quantity with this.getUnit().inverse()}.
137         */
138        Quantity<?> inverse();
139
140       /**
141        * Returns this {@code Quantity} converted into another (compatible) {@code Unit}.
142        *
143        * @param unit the {@code Unit} to convert to.
144        * @return the converted result.
145        */
146        Quantity<Q> to(Unit<Q> unit);
147    
148       /**
149        * Casts this quantity to a parameterized unit of specified nature or throw a
150        * <code>ClassCastException</code> if the dimension of the specified
151        * quantity and this measure unit's dimension do not match. For example:<br/>
152        * <code>
153        *     Quantity<Length> length = BaseQuantity.of("2 km").asType(Length.class);
154        * </code>
155        * or
156        * <code>
157        *      Quantity<Speed> C = length.multiply(299792458).divide(second).asType(Speed.class);
158        * </code>
159        *
160        * @param  <T> The type of the quantity.
161        * @param  type the quantity class identifying the nature of the quantity.
162        * @return this quantity parameterized with the specified type.
163        * @throws ClassCastException
164        *             if the dimension of this unit is different from the specified
165        *             quantity dimension.
166        * @throws UnsupportedOperationException
167        *             if the specified quantity class does not have a public static
168        *             field named "UNIT" holding the SI unit for the quantity.
169        * @see Unit#asType(Class)
170        */
171        <T extends Quantity<T>> Quantity<T> asType(Class<T> type) throws ClassCastException;
172
173        /**
174         * Returns the value of this {@code Quantity}.
175         *
176         * @return a value.
177         */
178        Number getValue();
179
180        /**
181         * Returns the unit of this {@code Quantity}.
182         *
183         * @return the unit (shall not be {@code null}).
184         */
185        Unit<Q> getUnit();
186}