/** * Copyright (C) 2019 Adrien Hopkins * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ package unitConverter.unit; import java.util.Objects; import unitConverter.dimension.UnitDimension; /** * The default abstract implementation of the {@code Unit} interface. * * @author Adrien Hopkins * @since 2019-01-25 */ public abstract class AbstractUnit implements Unit { /** * The number of units created, including base units. * * @since 2019-01-02 */ private static long unitCount = 0; /** * The number of base units created. * * @since 2019-01-02 */ private static long baseUnitCount = 0; /** * @return number of base units created * @since 2019-01-02 */ public static final long getBaseUnitCount() { return baseUnitCount; } /** * @return number of units created * @since 2019-01-02 */ public static final long getUnitCount() { return unitCount; } /** * Increments the number of base units. * * @since 2019-01-15 */ public static final void incrementBaseUnitCounter() { baseUnitCount++; } /** * Increments the number of units. * * @since 2019-01-15 */ public static final void incrementUnitCounter() { unitCount++; } /** * The dimension, or what the unit measures. * * @since 2018-12-22 */ private final UnitDimension dimension; /** * The unit's base unit. Values converted by {@code convertFromBase} and {@code convertToBase} are expressed in this * unit. * * @since 2018-12-22 */ private final BaseUnit base; /** * The system that this unit is a part of. * * @since 2018-12-23 */ private final UnitSystem system; /** * Creates the {@code AbstractUnit}. * * @param base * unit's base * @throws NullPointerException * if name, symbol or base is null * @since 2018-12-22 */ public AbstractUnit(final BaseUnit base) { this.base = Objects.requireNonNull(base, "base must not be null."); this.dimension = this.base.getDimension(); this.system = this.base.getSystem(); } /** * Creates the {@code AbstractUnit} using a unique dimension. This constructor is for making base units and should * only be used by {@code BaseUnit}. * * @param dimension * dimension measured by unit * @param system * system that unit is a part of * @throws AssertionError * if this constructor is not run by {@code BaseUnit} or a subclass * @throws NullPointerException * if name, symbol or dimension is null * @since 2018-12-23 */ AbstractUnit(final UnitDimension dimension, final UnitSystem system) { // try to set this as a base unit if (this instanceof BaseUnit) { this.base = (BaseUnit) this; } else throw new AssertionError(); this.dimension = Objects.requireNonNull(dimension, "dimension must not be null."); this.system = Objects.requireNonNull(system, "system must not be null."); } @Override public final BaseUnit getBase() { return this.base; } @Override public final UnitDimension getDimension() { return this.dimension; } @Override public final UnitSystem getSystem() { return this.system; } // TODO document and revise units' toString methods @Override public String toString() { return String.format("%s-derived unit of dimension %s", this.getSystem(), this.getDimension()); } }