Last active
August 29, 2015 14:26
-
-
Save sshark/22fa4092a73b64916248 to your computer and use it in GitHub Desktop.
Using temperatures Celcius, Fahrenheit and Kelvin as an AnyVal example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * To be a valid value class, the following rules must be followed (taken from Programming Scala 2nd Ed.): | |
| * 1. The value class has one and only one public val argument (as of Scala 2.11, | |
| * the argument can also be nonpublic). | |
| * 2. The type of the argument must not be a value class itself. | |
| * 3. If the value class is parameterized, the @specialized annotation can’t be used. | |
| * 4. The value class doesn’t define secondary constructors. | |
| * 5. The value class defines only methods, but no other vals and no vars. | |
| * 6. However, the value class can’t override equals and hashCode. | |
| * 7. The value class defines no nested traits, classes, or objects. | |
| * 8. The value class cannot be subclassed. | |
| * 9. The value class can only inherit from universal traits. An universal trait extends from Any. | |
| * 10. The value class must be a top-level type or a member of an object that can be referenced | |
| */ | |
| trait Temperature extends Any { | |
| def toKelvin: Kelvin | |
| def toCelcius: Celcius | |
| def toFahrenheit: Fahrenheit | |
| } | |
| class Kelvin(val t: Double) extends AnyVal with Temperature { | |
| override def toKelvin = new Kelvin(t) | |
| override def toCelcius = new Celcius(t - 273.15d) | |
| override def toFahrenheit = new Fahrenheit((t - 273.15d) * 1.8 + 32.0) | |
| } | |
| class Fahrenheit(val t: Double) extends AnyVal with Temperature { | |
| override def toKelvin = new Kelvin((t + 459.67) * 5/9) | |
| override def toCelcius = new Celcius((t - 32) / 1.8) | |
| override def toFahrenheit = new Fahrenheit(t) | |
| } | |
| class Celcius(val t: Double) extends AnyVal with Temperature { | |
| override def toKelvin = new Kelvin(t + 273.15) | |
| override def toCelcius = new Celcius(t) | |
| override def toFahrenheit = new Fahrenheit(t * 1.8 + 32.0) | |
| } | |
| class TemperatureReporter(t: Temperature) { | |
| override def toString = "[" + t.toKelvin.t + "K, " + t.toFahrenheit.t + "F, " + | |
| t.toCelcius.t + "C]" | |
| } | |
| Seq(new Celcius(100), new Fahrenheit(212), new Kelvin(373.15)).foreach( | |
| t => println(new TemperatureReporter(t))) | |
| Seq(new Celcius(0), new Fahrenheit(32), new Kelvin(273.15)).foreach( | |
| t => println(new TemperatureReporter(t))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment