Skip to content

Commit

Permalink
Add closed_types.md to course text
Browse files Browse the repository at this point in the history
  • Loading branch information
btj committed Dec 1, 2023
1 parent 53a6c9c commit 11b7878
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 13 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
- Concepts: interfaces, multiple inheritance, static fields, the Singleton pattern
- [Implementation inheritance](implementation_inheritance.md)
- Concepts: Inheritance of fields and methods, `super` constructor calls, `super` method calls
- [Closed types](closed_types.md)
- Concepts: types with a closed set of instances, enum classes, types with a closed set of direct subtypes, sealed types, switch statements and expressions
- [Lists, sets, and maps](collections.md)
- Concepts: the List, Set, and Map abstract datatypes (ADTs); the ArrayList, LinkedList, HashSet, and HashMap data structures; the Java Collections Framework

Expand Down
31 changes: 18 additions & 13 deletions closed_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public final class Score {
public static final Score THIRTY = new Score(2, "THIRTY", 30);
public static final Score FORTY = new Score(3, "FORTY", 40) {
@Overrride
public Score next() { throw new UnsupportedOperationException("There is no next score"); }
public Score next() { throw new UnsupportedOperationException(); }
};
private static final Score[] values = {LOVE, FIFTEEN, THIRTY, FORTY};

Expand Down Expand Up @@ -49,7 +49,7 @@ public enum Score {
THIRTY(30),
FORTY(40) {
@Override
public Score next() { throw new UnsupportedOperationException("There is no next score"); }
public Score next() { throw new UnsupportedOperationException(); }
};

private final int value;
Expand Down Expand Up @@ -90,16 +90,21 @@ public String getScoreInFrench(Score score) {
Consider an interface GameState whose instances are intended to represent the various states that a game of tennis can be in:
```java
public interface GameState {
public record Regular(Score servingPlayerScore, Score receivingPlayerScore) implements GameState {
Regular { Objects.requireNonNull(servingPlayerScore); Objects.requireNonNull(receivingPlayerScore); }
public record Regular(Score serverScore, Score receiverScore) implements GameState {
Regular {
Objects.requireNonNull(serverScore);
Objects.requireNonNull(receiverScore);
}
}
public record Advantage(boolean servingPlayer) implements GameState {}
public record Won(boolean servingPlayer) implements GameState {}
public record Advantage(boolean server) implements GameState {}
public record Won(boolean server) implements GameState {}
}
```
We can prevent clients from defining additional classes that implement interface GameState by declaring it as *sealed*:
```java
public sealed interface GameState permits GameState.Regular, GameState.Advantage, GameState.Won { /* ... */ }
public sealed interface GameState
permits GameState.Regular, GameState.Advantage, GameState.Won
{ /* ... */ }
```
In this example, we can in fact just leave out the `permits` clause. This means only direct subtypes declared in the same file are allowed:
```java
Expand All @@ -112,12 +117,12 @@ We can use switch statements or switch expressions to perform case analysis on a
```java
public String toString(GameState state) {
return switch (state) {
case GameState.Regular(var servingPlayerScore, var receivingPlayerScore) ->
servingPlayerScore.value() + "-" + receivingPlayerScore.value();
case GameState.Advantage(var servingPlayer) ->
"advantage " + (servingPlayer ? "serving" : "receiving") + " player";
case GameState.Won(var servingPlayer) ->
"won by the " + (servingPlayer ? "serving" : "receiving") + " player";
case GameState.Regular(var serverScore, var receiverScore) ->
serverScore.value() + "-" + receiverScore.value();
case GameState.Advantage(var server) ->
"advantage " + (server ? "server" : "receiver");
case GameState.Won(var server) ->
"won by the " + (server ? "server" : "receiver");
};
}
```
5 changes: 5 additions & 0 deletions latex.template
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,13 @@ $if(listings)$
language=java,
basicstyle=\ttfamily\footnotesize,
commentstyle=\color{ogpjavadoc}\ttfamily\footnotesize,
morekeywords={enum,record,sealed,permits},
frame=lines,
rulecolor=\color{black}}
\lstset{
extendedchars=true,
literate={é}{{\'e}}1,
}
%\lstset{xleftmargin=-2cm,xrightmargin=-2cm}
$endif$
$if(lhs)$
Expand Down
2 changes: 2 additions & 0 deletions make-pdf.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pandoc -o course-notes.html -f gfm \
behavioral_subtyping.md \
interfaces.md \
implementation_inheritance.md \
closed_types.md \
collections.md \
entity_relationship_abstractions.md \
multi_class_abstractions.md \
Expand All @@ -42,6 +43,7 @@ sed "${SED_IN_PLACE[@]}" \
-e 's/\\chapter{Behavioral subtyping: modular reasoning about programs that use dynamic binding}/\\chapter[Modular reasoning about dynamic binding]{Behavioral subtyping: modular reasoning about programs that use dynamic binding}/' \
-e 's/\\section{Modular reasoning about programs that use dynamic binding}/\\section[Modular reasoning about dynamic binding]{Modular reasoning about programs that use dynamic binding}/' \
-e 's/\\chapter{Iterators}/\\part{Part IV: Advanced Topics}\\chapter{Iterators}/' \
-e 's/language=Java/language=Java,morekeywords={enum,record,sealed,permits}/g' \
course-notes.tex
pdflatex course-notes.tex
pdflatex course-notes.tex

0 comments on commit 11b7878

Please sign in to comment.