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