You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/_spec/05-classes-and-objects.md
+341Lines changed: 341 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -41,6 +41,8 @@ The list of parents of a template must be well-formed.
41
41
This means that the class denoted by the superclass constructor ´sc´ must be a subclass of the superclasses of all the traits ´mt_1, ..., mt_n´.
42
42
In other words, the non-trait classes inherited by a template form a chain in the inheritance hierarchy which starts with the template's superclass.
43
43
44
+
It is forbidden for a template's superclass constructor ´sc´ to be an [enum class](#enum-definitions), unless the template is the implementation of an [enum case](#enum-definitions) of ´sc´.
45
+
44
46
The _least proper supertype_ of a template is the class type or [compound type](03-types.html#compound-types) consisting of all its parent class types.
45
47
46
48
The statement sequence ´\mathit{stats}´ contains member definitions that define new members or overwrite members in the parent classes.
@@ -801,3 +803,342 @@ Generally, a _companion module_ of a class is an object which has the same name
801
803
Conversely, the class is called the _companion class_ of the module.
802
804
803
805
Very much like a concrete class definition, an object definition may still contain declarations of abstract type members, but not of abstract term members.
806
+
807
+
## Enum Definitions
808
+
809
+
<!-- TODO: Agree with NTs of rest of spec -->
810
+
```ebnf
811
+
TmplDef ::= ‘enum’ EnumDef
812
+
EnumDef ::= id ClassConstr [‘extends’ [ConstrApps]] EnumBody
EnumCase ::= ‘case’ (id ClassConstr [‘extends’ ConstrApps] | ids)
817
+
```
818
+
819
+
An _enum definition_ implies the definition of an _enum class_, a companion object, and one or more _enum cases_.
820
+
821
+
Enum definitions are useful to encode both Generalised Algebraic Data Types and Enumerated Types.
822
+
823
+
The compiler expands enum definitions to code that only uses Scala's other language features.
824
+
As such, enum definitions in Scala are convenient _syntactic sugar_, but they are not essential to understand Scala's core.
825
+
826
+
We now explain the expansion of enum definitions in detail.
827
+
First, some terminology and notational conventions:
828
+
829
+
- We use ´E´ as a name of an enum definition, and ´C´ as a name of an enum case that appears in ´E´.
830
+
- We use `<...>` for syntactic constructs that in some circumstances might be empty.
831
+
For instance, `<value-params>` represents one or more parameter lists `(´\mathit{ps}_1\,´)...(´\mathit{ps}_n´)` or nothing at all.
832
+
- Enum classes fall into two categories:
833
+
-_parameterized_ enum classes have at least one of the following:
834
+
- a type parameter section, denoted as `[´\mathit{tps}\,´]`;
835
+
- one or more (possibly empty) parameter sections, denoted as `(´\mathit{ps}_1\,´)...(´\mathit{ps}_n´)`.
836
+
-_unparameterized_ enum classes have no type parameter sections and no parameter sections.
837
+
- Enum cases fall into three categories:
838
+
839
+
-_Class cases_ are those cases that are parameterized, either with a type parameter section `[´\mathit{tps}\,´]` or with one or more (possibly empty) parameter sections `(´\mathit{ps}_1\,´)...(´\mathit{ps}_n´)`.
840
+
-_Simple cases_ are cases of an unparameterized enum that have neither parameters nor an extends clause or body.
841
+
That is, they consist of a name only.
842
+
-_Value cases_ are all cases that do not have a parameter section but that do have a (possibly generated) `extends` clause and/or a body.
843
+
844
+
- Simple cases and value cases are collectively called _singleton cases_.
845
+
846
+
###### Example
847
+
848
+
An example enum for a `Planet` enumeration can be given as
Rules (4) to (6) define `extends` clauses for cases that are missing them.
899
+
Rules (7) to (9) define how such cases with `extends` clauses map into `case class`es or `val`s.
900
+
901
+
1. An `enum` definition
902
+
```scala
903
+
enum ´E´ ... { <defs> <cases> }
904
+
```
905
+
expands to a `sealed abstract` classthatextends the `scala.reflect.Enum` traitand an associated companion objectthat contains the defined cases, expanded according to rules (2-8).
906
+
Theenumclass starts with a compiler-generated importthatimportsthenames`<caseIds>`ofallcasessothattheycanbeusedwithoutprefixintheclass.
907
+
```scala
908
+
sealedabstractclass ´E´ ... extends <parents> with scala.reflect.Enum {
909
+
import ´E´.{ <caseIds> }
910
+
<defs>
911
+
}
912
+
object ´E´ { <cases> }
913
+
```
914
+
915
+
2. A singleton case consisting of a comma-separated list of enumnames
916
+
```scala
917
+
case ´C_1´, ..., ´C_n´
918
+
```
919
+
expands to
920
+
```scala
921
+
case ´C_1´; ...; case ´C_n´
922
+
```
923
+
Any modifiers or annotations on the original case extend to all expanded cases.
924
+
This result is then further rewritten by either (3 or 4).
925
+
926
+
3. A singleton case without an extends clause
927
+
```scala
928
+
case ´C´
929
+
```
930
+
of an unparameterized enum `´E´` expands to the following simple enum case in `´E´`'s companion object:
931
+
```scala
932
+
val ´C´ = $new(n, "C")
933
+
```
934
+
Here, `$new` is a private method that creates an instance of ´E´ (see below).
where `´\mathit{n}´` is the ordinal number of the case in the companion object, starting from 0.
1007
+
**NOTE:** It is an error if a class case refers to a type parameter of `´E´` in a parameter type in `<type-params>` or `<value-params>` or in a type argument of `<parents>`, unless that parameter is already a type parameter of the case, i.e. the parameter name is defined in `<type-params>`.
1008
+
1009
+
###### Superclass of an enum case
1010
+
1011
+
an enum case (singleton or class) with explicit extends clause
1012
+
```scala
1013
+
case ´C´ <type-params> <value-params> extends <parents>
1014
+
```
1015
+
1016
+
must extend the parent enum `´E´` as the first parent of `<parents>`.
1017
+
1018
+
###### Example
1019
+
Consider the enumeration `RGB`, consisting of simple enum cases:
1020
+
```scala
1021
+
enumRGB:
1022
+
caseRed, Green, Blue
1023
+
```
1024
+
1025
+
The three simple cases will expand as follows in the companion of `RGB`:
1026
+
1027
+
```scala
1028
+
valRed= $new(0, "Red")
1029
+
valGreen= $new(1, "Green")
1030
+
valBlue= $new(2, "Blue")
1031
+
1032
+
privatedef$new(_$ordinal: Int, $name: String) =
1033
+
newRGBwith scala.runtime.EnumValue:
1034
+
defordinal= _$ordinal
1035
+
overridedefproductPrefix= $name
1036
+
overridedeftoString= $name
1037
+
```
1038
+
1039
+
1040
+
###### Example
1041
+
1042
+
Consider the more complex enumeration `Color`, consisting of value enum cases:
1043
+
```scala
1044
+
enumColor(valrgb:Int):
1045
+
caseRedextendsColor(0xFF0000)
1046
+
caseGreenextendsColor(0x00FF00)
1047
+
caseBlueextendsColor(0x0000FF)
1048
+
```
1049
+
1050
+
The three value cases will expand as follows in the companion of `Color`:
1051
+
1052
+
```scala
1053
+
valRed=newColor(0xFF0000):
1054
+
defordinal:Int=0
1055
+
overridedefproductPrefix:String="Red"
1056
+
overridedeftoString:String="Red"
1057
+
valGreen=newColor(0x00FF00):
1058
+
defordinal:Int=1
1059
+
overridedefproductPrefix:String="Green"
1060
+
overridedeftoString:String="Green"
1061
+
valBlue=newColor(0x0000FF):
1062
+
defordinal:Int=2
1063
+
overridedefproductPrefix:String="Blue"
1064
+
overridedeftoString:String="Blue"
1065
+
```
1066
+
1067
+
### Widening of enum cases post-construction
1068
+
The compiler-generated `apply` and `copy` methods of an class enum case
1069
+
```scala
1070
+
case ´C´[´\mathit{tps}\,´](´\mathit{ps}_1\,´)...(´\mathit{ps}_n´) extends ´P_1´, ..., ´P_n´
1071
+
```
1072
+
are treated specially.
1073
+
A call `´C´[´\mathit{tps}\,´](´\mathit{ps}_1\,´)...(´\mathit{ps}_n´)` of the `apply` method is ascribed the underlying type `´P_1´ & ... & ´P_n´` (dropping any [transparent traits](../other-new-features/transparent-traits.md)) as long as that type is still compatible with the expected type at the point of application.
1074
+
A call `t.copy[´\mathit{tps}\,´](´\mathit{ps}_1\,´)...(´\mathit{ps}_n´)` of `´C´`'s `copy` method is treated in the same way.
1075
+
1076
+
### Translation of enums with only singleton cases
1077
+
1078
+
An enum `´E´` (possibly generic) that defines one or more singleton cases, and no class cases will define the following additional synthetic members in its companion object (where `´E'´` denotes `´E´` with any type parameters replaced by wildcards):
1079
+
1080
+
- A method `valueOf(name: String): ´E'´`.
1081
+
It returns the singleton case value whose identifier is `name`.
1082
+
- A method `values` which returns an `Array[´E'´]` of all singleton case values defined by `E`, in the order of their definitions.
1083
+
1084
+
### Factory method for simple enum cases
1085
+
1086
+
If an enum `´E´` contains at least one simple case, its companion object will define in addition:
1087
+
1088
+
- A private method `$new` which defines a new simple case value with given ordinal number and name.
1089
+
This method can be thought as being defined as follows.
1090
+
1091
+
```scala
1092
+
privatedef$new(_$ordinal: Int, $name: String): ´E´ with runtime.EnumValue
1093
+
```
1094
+
-`$new` returns a new instance of an anonymous class which implements the abstract `Product` methods that it inherits from `Enum`.
1095
+
- if `´E´` inherits from `java.lang.Enum` the anonymous class does not override the `ordinal` or `toString` methods, as these are final in `java.lang.Enum`.
1096
+
Additionally `productPrefix` will delegate to `this.name`.
1097
+
1098
+
### Translation of Java-compatible enums
1099
+
1100
+
A Java-compatible enum is an enum that extends `java.lang.Enum`.
1101
+
The translation rules are the same as above, with the reservations defined in this section.
1102
+
1103
+
- It is a compile-time error for a Java-compatible enum to have class cases.
1104
+
1105
+
- Cases such as `case C` expand to a `@static val` as opposed to a `val`.
1106
+
This allows them to be generated as static fields of the enum type, thus ensuring they are represented the same way as Java enums.
1107
+
1108
+
### Scopes for Enum Cases
1109
+
1110
+
A case in an `enum` is treated similarly to a secondary constructor.
1111
+
It can access neither the enclosing `enum` using `this`, nor its value parameters or instance members using simple identifiers.
1112
+
1113
+
Even though translated enum cases are located in the enum's companion object, referencing this object or its members via `this` or a simple identifier is also illegal.
1114
+
The compiler typechecks enum cases in the scope of the enclosing companion object but flags any such illegal accesses as errors.
1115
+
1116
+
### Variance for Type Parameters
1117
+
1118
+
A parameterized enum case ´C´ of enum ´E´ with _inferred_ type parameters will copy variance annotations.
1119
+
e.g. type parameter ´T_{i}´ from ´E´ will have the same variance as type parameter `´T'_{i}´` in ´C´.
1120
+
1121
+
###### Example
1122
+
1123
+
The following enum `View` has a contravariant type parameter ´T´ and a single case `Refl`, representing a function mapping a type `T` to itself:
<!-- TODO: Could not find more info on which non-Product methods case class automatically define -->
346
346
All case classes automatically extend the `Product` trait (and generate synthetic methods to conform to it) (but not `Product´n´`), and define a `_´n´` method for each of their arguments.
347
347
348
+
### Trait `Enum`
349
+
<!-- TODO: Move somewhere else ? -->
350
+
All enum definitions automatically extend the `reflect.Enum` trait (and generate synthetic methods to conform to it).
351
+
348
352
### Class `Array`
349
353
350
354
All operations on arrays desugar to the corresponding operations of the underlying platform.
0 commit comments