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