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 Unit
051 * @see <a href="http://en.wikipedia.org/wiki/Quantity">Wikipedia: Quantity</a>
052 * @see <a href="http://martinfowler.com/eaaDev/quantity.html">Martin Fowler - Quantity</a>
053 * @version 1.0, August 8, 2016
054 * @since 1.0
055 */
056public interface Quantity<Q extends Quantity<Q>> {
057
058  /**
059   * Returns the sum of this {@code Quantity} with the one specified.
060   *
061   * @param augend
062   *          the {@code Quantity} to be added.
063   * @return {@code this + augend}.
064   */
065  Quantity<Q> add(Quantity<Q> augend);
066
067  /**
068   * Returns the difference between this {@code Quantity} and the one specified.
069   *
070   * @param subtrahend
071   *          the {@code Quantity} to be subtracted.
072   * @return <code>this - that</code>.
073   */
074  Quantity<Q> subtract(Quantity<Q> subtrahend);
075
076  /**
077   * Returns the product of this {@code Quantity} divided by the {@code Quantity} specified.
078   *
079   * @throws ClassCastException
080   *           if the type of an element in the specified operation is incompatible with this quantity (<a href="#optional-restrictions">optional</a>)
081   *
082   * @param divisor
083   *          the {@code Quantity} divisor.
084   * @return <code>this / that</code>.
085   */
086  Quantity<?> divide(Quantity<?> divisor);
087
088  /**
089   * Returns the product of this {@code Quantity} divided by the {@code Number} specified.
090   *
091   * @param divisor
092   *          the {@code Number} divisor.
093   * @return <code>this / that</code>.
094   */
095  Quantity<Q> divide(Number divisor);
096
097  /**
098   * Returns the product of this {@code Quantity} with the one specified.
099   *
100   * @throws ClassCastException
101   *           if the type of an element in the specified operation is incompatible with this quantity (<a href="#optional-restrictions">optional</a>)
102   *
103   * @param multiplier
104   *          the {@code Quantity} multiplier.
105   * @return <code>this * multiplier</code>.
106   */
107  Quantity<?> multiply(Quantity<?> multiplier);
108
109  /**
110   * Returns the product of this {@code Quantity} with the {@code Number} value specified.
111   *
112   * @param multiplier
113   *          the {@code Number} multiplier.
114   * @return <code>this * multiplier</code>.
115   */
116  Quantity<Q> multiply(Number multiplier);
117
118  /**
119   * Returns a {@code Quantity} whose unit is {@code unit.inverse()}.
120   *
121   * @return {@code Quantity with this.getUnit().inverse()}.
122   */
123  Quantity<?> inverse();
124
125  /**
126   * Returns this {@code Quantity} converted into another (compatible) {@code Unit}.
127   *
128   * @param unit
129   *          the {@code Unit} to convert to.
130   * @return the converted result.
131   */
132  Quantity<Q> to(Unit<Q> unit);
133
134  /**
135   * Casts this quantity to a parameterized unit of specified nature or throw a <code>ClassCastException</code> if the dimension of the specified
136   * quantity and this measure unit's dimension do not match. For example:
137   * <p>
138   * <code>
139   *     {@literal Quantity<Length>} length = Quantities.getQuantity("2 km").asType(Length.class);
140   * </code> or <code>
141   *     {@literal Quantity<Speed>} C = length.multiply(299792458).divide(second).asType(Speed.class);
142   * </code>
143   * </p>
144   *
145   * @param <T>
146   *          The type of the quantity.
147   * @param type
148   *          the quantity class identifying the nature of the quantity.
149   * @return this quantity parameterized with the specified type.
150   * @throws ClassCastException
151   *           if the dimension of this unit is different from the specified quantity dimension.
152   * @throws UnsupportedOperationException
153   *           if the specified quantity class does not have a SI unit for the quantity.
154   * @see Unit#asType(Class)
155   */
156  <T extends Quantity<T>> Quantity<T> asType(Class<T> type) throws ClassCastException;
157
158  /**
159   * Returns the value of this {@code Quantity}.
160   *
161   * @return a value.
162   */
163  Number getValue();
164
165  /**
166   * Returns the unit of this {@code Quantity}.
167   *
168   * @return the unit (shall not be {@code null}).
169   */
170  Unit<Q> getUnit();
171}