Commit 8be2e98e authored by Dr. Martin Goik's avatar Dr. Martin Goik

Enum exercises

parent 4ff4d221
This diff is collapsed.
......@@ -690,6 +690,68 @@ true <emphasis role="red">if this object is the same as the obj argument</emphas
</qandaentry>
</qandadiv>
</qandaset>
<qandaset defaultlabel="qanda"
xml:id="sd1_quanda_inheritDirectionAlternateImpl">
<title>Alternate implementation of opposite directions</title>
<qandadiv>
<qandaentry>
<question>
<para>Provide a different implementation of your <methodname
xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/blob/master/Doc/Sd1/Ref/ObjectsAndClasses/Enum/Compass_2.0/src/main/java/de/hdm_stuttgart/mi/sd1/direction/Direction.java#L28">opposite()</methodname>
from <xref linkend="sd1_qanda_enumDirectionNeighbours"/>. Follow
<uri
xlink:href="https://stackoverflow.com/questions/5678309/illegal-forward-reference-and-enums#answer-49409377">https://stackoverflow.com/questions/5678309/illegal-forward-reference-and-enums#answer-49409377</uri>.
Start by investigating both <methodname
xlink:href="http://www.java2s.com/Tutorial/Java/0040__Data-Type/Usingthebuiltinenumerationmethodsvalues.htm">values()</methodname>
and <methodname
xlink:href="https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/lang/Enum.html#ordinal()">ordinal()</methodname>.</para>
</question>
<answer>
<para>We observe the following ordinal values:</para>
<informaltable border="0">
<tr>
<td valign="top"><programlisting language="java">public enum Direction {
N( 0, "north"), // 0
NE( 45, "north by east"), // 1
E( 90, "east"), // 2
SE(135, "south by east"), // 3
S( 180, "south"), // 4
SW(225, "south by west"), // 5
W( 270, "west"), // 6
NW(315, "north by west"); // 7
...</programlisting></td>
<td valign="top"><programlisting language="none">public Direction opposite() {
switch (this) {
case N: return S; // <emphasis role="red">0 --&gt; 4</emphasis>
case NE: return SW; // <emphasis role="red">1 --&gt; 5</emphasis>
case E: return W; // <emphasis role="red">2 --&gt; 6</emphasis>
case SE: return NW; // <emphasis role="red">3 --&gt; 7</emphasis>
case S: return N; // <emphasis role="red">4 --&gt; 0</emphasis>
case SW: return NE; // <emphasis role="red">5 --&gt; 1</emphasis>
case W: return E; // <emphasis role="red">6 --&gt; 2</emphasis>
case NW: return SE; // <emphasis role="red">7 --&gt; 3</emphasis>
...</programlisting></td>
</tr>
</informaltable>
<para>We are thus left implementing an integer shift <code>(0, 1,
2, 3, 4, 5, 6, 7)</code> to <code>(4, 5, 6, 7, 0, 1, 2,
3)</code>:</para>
<programlisting language="java">public Direction <link
xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/blob/master/Doc/Sd1/Ref/ObjectsAndClasses/Enum/Compass_3.0/src/main/java/de/hdm_stuttgart/mi/sd1/direction/Direction.java#L28">opposite()</link> {
return values()[ (ordinal() + 4) % 8];
}</programlisting>
</answer>
</qandaentry>
</qandadiv>
</qandaset>
</section>
<section xml:id="sd1_inherit_sect_final">
......
......@@ -10568,6 +10568,193 @@ class_wrapper_private.Day'</emphasis></screen></td>
linkend="sd1_fig_preventUndesiredDayCreation"><code
language="java">enum</code> external instance creation</link>.</para>
</figure>
<qandaset defaultlabel="qanda" xml:id="sd1_qanda_enumDirections">
<title>Compass directions</title>
<qandadiv>
<qandaentry>
<question>
<para>We consider an eight direction compass rose:</para>
<informalfigure>
<mediaobject>
<imageobject>
<imagedata fileref="Ref/ObjectsAndClasses/Enum/windrose.svg"/>
</imageobject>
</mediaobject>
</informalfigure>
<para>Provide an <code language="java">enum</code>
<classname>Direction</classname> to be usable in the following
manner:</para>
<informaltable border="0">
<tr>
<td valign="top"><programlisting language="java">final Direction northWest = Direction.NW;
System.out.println(northWest);</programlisting></td>
<td valign="top"><screen>north by west (315°)</screen></td>
</tr>
</informaltable>
<tip>
<para>Provide an appropriate constructor among with suitable
«internal» instance attributes and a corresponding <methodname
xlink:href="https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/lang/Object.html#toString()">toString()</methodname>
method.</para>
</tip>
</question>
<answer>
<para>The desired output contains both a given direction's
description and degree value. We thus start by:</para>
<programlisting language="java">public enum Direction {
int degree;
String fullName;
}</programlisting>
<para>For creating a <classname>Direction</classname> instance a
constructor accepting both values is being required:</para>
<programlisting language="java">public enum Direction {
N(0, "north"); <co linkends="sd1_qanda_enumDirectionsConstruct-1.2"
xml:id="sd1_qanda_enumDirectionsConstruct-1.2-co"/>
Direction(final int degree, final String fullName) { <co
linkends="sd1_qanda_enumDirectionsConstruct-2.2"
xml:id="sd1_qanda_enumDirectionsConstruct-2.2-co"/>
this.degree = degree;
this.fullName = fullName;
}
public final int degree; <co linkends="sd1_qanda_enumDirectionsConstruct-3"
xml:id="sd1_qanda_enumDirectionsConstruct-3.2-co"/>
public final String fullName;
}</programlisting>
<calloutlist>
<callout arearefs="sd1_qanda_enumDirectionsConstruct-1.2-co"
xml:id="sd1_qanda_enumDirectionsConstruct-1.2">
<para>For the sake of simplicity we only create the «north»
direction here.</para>
</callout>
<callout arearefs="sd1_qanda_enumDirectionsConstruct-2.2-co"
xml:id="sd1_qanda_enumDirectionsConstruct-2.2">
<para>Constructor accepting:</para>
<orderedlist>
<listitem>
<para>A degree value e.g. 90° representing «eastern»
direction.</para>
</listitem>
<listitem>
<para>An informal name e.g. «east».</para>
</listitem>
</orderedlist>
</callout>
<callout arearefs="sd1_qanda_enumDirectionsConstruct-3.2-co"
xml:id="sd1_qanda_enumDirectionsConstruct-3">
<para>Two <code language="java">public</code> attributes
representing both a direction's degree value and its
informal name.</para>
</callout>
</calloutlist>
<para>For creating output texts like <abbrev>e.g.</abbrev>
<code>north by west (315°)</code> we need a <methodname
xlink:href="https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/lang/Object.html#toString()">toString()</methodname>
method. Also adding the yet missing directions our final result
looks like:</para>
<programlisting language="java">public enum Direction {
N( 0, "north"),
NE( 45, "north by east"),
E( 90, "east"),
SE(135, "south by east"),
S( 180, "south"),
SW(225, "south by west"),
W( 270, "west"),
NW(315, "north by west");
Direction(final int degree, final String fullName) {
this.degree = degree;
this.fullName = fullName;
}
@Override
public String toString() {
return fullName + " (" + degree + "°)";
}
public final int degree;
public final String fullName;
}</programlisting>
</answer>
</qandaentry>
</qandadiv>
</qandaset>
<qandaset defaultlabel="qanda"
xml:id="sd1_qanda_enumDirectionNeighbours">
<title>Compass direction neighbours</title>
<qandadiv>
<qandaentry>
<question>
<para>We would like to «invert» a given direction
<abbrev>e.g.</abbrev> turning <code>N</code> to <code>S</code>
and vice versa. Extend <xref
linkend="sd1_qanda_enumDirectionNeighbours"/> by adding an
<methodname>opposite()</methodname> method to be used
like:</para>
<informaltable border="0">
<tr>
<td valign="top"><programlisting language="java">final Direction southWest = Direction.SW;
System.out.println("Direction: " + southWest);
System.out.println(" Opposite: " + southWest.opposite());</programlisting></td>
<td valign="top"><screen>Direction: south by west (225°)
Opposite: north by east (45°)</screen></td>
</tr>
</informaltable>
</question>
<answer>
<para>Using <code language="java">switch</code> allows for a
straightforward solution:</para>
<programlisting language="java">public enum Direction {
...
public Direction opposite() {
switch (this) {
case N: return S;
case NE: return SW;
case E: return W;
case SE: return NW;
case S: return N;
case SW: return NE;
case W: return E;
case NW: return SE;
default: return null; // Unreachable, but required for keeping the compiler happy.
}
}
...
}</programlisting>
</answer>
</qandaentry>
</qandadiv>
</qandaset>
</section>
</section>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment