Skip to content
Snippets Groups Projects
inheritance.xml 70.5 KiB
Newer Older
Goik Martin's avatar
Goik Martin committed
<?xml version="1.0" encoding="UTF-8"?>
Goik Martin's avatar
Goik Martin committed
<chapter annotations="slide" version="5.1" xml:id="sw1ChapterInheritance"
Goik Martin's avatar
Goik Martin committed
         xmlns="http://docbook.org/ns/docbook"
         xmlns:xlink="http://www.w3.org/1999/xlink"
         xmlns:xila="http://www.w3.org/2001/XInclude/local-attributes"
Goik Martin's avatar
Goik Martin committed
         xmlns:xi="http://www.w3.org/2001/XInclude"
         xmlns:svg="http://www.w3.org/2000/svg"
         xmlns:ns="http://docbook.org/ns/transclusion"
Goik Martin's avatar
Goik Martin committed
         xmlns:m="http://www.w3.org/1998/Math/MathML"
         xmlns:html="http://www.w3.org/1999/xhtml"
         xmlns:db="http://docbook.org/ns/docbook">
  <title>Inheritance</title>
Goik Martin's avatar
Goik Martin committed

  <figure xml:id="sd1_inherit_fig_guessWho">
    <title>Guess who's inheriting the money</title>

    <mediaobject>
      <imageobject>
Goik Martin's avatar
Goik Martin committed
        <imagedata fileref="Fig/guessWho.svg"/>
      </imageobject>
    </mediaobject>
  </figure>

  <figure xml:id="sd1_inherit_fig_biologicalInherit">
    <title>Biology and inheritance</title>

    <mediaobject>
      <imageobject>
Goik Martin's avatar
Goik Martin committed
        <imagedata fileref="Fig/biologicalInheritance.svg"/>
      </imageobject>
    </mediaobject>
  </figure>

Goik Martin's avatar
Goik Martin committed
  <figure xml:id="sda_inherit_fig_DuplicateCode">
Goik Martin's avatar
Goik Martin committed
    <title>Duplicate code</title>

    <informaltable border="0">
      <tr>
        <td valign="top"><programlisting language="none">public class Rectangle{
  // Center coordinate
Goik Martin's avatar
Goik Martin committed
  <emphasis role="red">private double x</emphasis>; <co
              linkends="sda_inherit_fig_DuplicateCode-1"
              xml:id="sda_inherit_fig_DuplicateCode-1-co"/>
  <emphasis role="red">private double y</emphasis>;

  <emphasis role="red">public void move
    (double dx, double dy){</emphasis> <co
Goik Martin's avatar
Goik Martin committed
              linkends="sda_inherit_fig_DuplicateCode-2"
              xml:id="sda_inherit_fig_DuplicateCode-2-co"/>
     <emphasis role="red">x += dx;
     y += dy;
  }</emphasis>
  private double width, height; <co linkends="sda_inherit_fig_DuplicateCode-3"
              xml:id="sda_inherit_fig_DuplicateCode-3-co"/> ...
Goik Martin's avatar
Goik Martin committed
}</programlisting></td>

        <td valign="top"><programlisting language="none">public class Circle {
Goik Martin's avatar
Goik Martin committed
  // Center coordinate
Goik Martin's avatar
Goik Martin committed
  <emphasis role="red">private double x</emphasis>; <coref
              linkend="sda_inherit_fig_DuplicateCode-1-co"/>
  <emphasis role="red">private double y</emphasis>;

  <emphasis role="red">public void move
    (double dx, double dy){</emphasis> <coref
Goik Martin's avatar
Goik Martin committed
              linkend="sda_inherit_fig_DuplicateCode-2-co"/>
     <emphasis role="red">x += dx;
     y += dy;
  }</emphasis>
  private double radius; <coref linkend="sda_inherit_fig_DuplicateCode-3-co"/> ...
Goik Martin's avatar
Goik Martin committed
}</programlisting></td>
      </tr>
    </informaltable>
Goik Martin's avatar
Goik Martin committed

    <calloutlist role="slideExclude">
      <callout arearefs="sda_inherit_fig_DuplicateCode-1-co"
               xml:id="sda_inherit_fig_DuplicateCode-1">
        <para>The center coordinate (<code language="java">x</code>|<code
        language="java">y)</code> appears both in
        <classname>Rectangle</classname> and
        <classname>Circle</classname>.</para>
      </callout>

      <callout arearefs="sda_inherit_fig_DuplicateCode-2-co"
               xml:id="sda_inherit_fig_DuplicateCode-2">
        <para>The move(...) method is being defined <emphasis
        role="bold">identically</emphasis> both in
        <classname>Rectangle</classname> and
        <classname>Circle</classname>!</para>
      </callout>

      <callout arearefs="sda_inherit_fig_DuplicateCode-3-co"
               xml:id="sda_inherit_fig_DuplicateCode-3">
        <itemizedlist>
          <listitem>
            <para><property>width</property> and <property>height</property>
            only appear in class <classname>Rectangle</classname>.</para>
          </listitem>
          <listitem>
            <para><property>radius</property> only appears in class
            Circle.</para>
          </listitem>
        </itemizedlist>
      </callout>
    </calloutlist>
  </figure>
  <figure xml:id="sda_inherit_fig_ideaFactorOutCommonCode">
    <title>Idea: Centralize common code</title>

    <itemizedlist>
      <listitem>
Goik Martin's avatar
Goik Martin committed
        <para>Create a parent class <classname>Shape</classname> containing
        common code portions.</para>
      </listitem>

      <listitem>
        <para>Relate both <classname>Rectangle</classname> and
Goik Martin's avatar
Goik Martin committed
        <classname>Circle</classname> to <classname>Shape</classname>.</para>
      </listitem>
    </itemizedlist>
  </figure>

Goik Martin's avatar
Goik Martin committed
  <figure xml:id="sda_inherit_fig_shapeCommonSpecific">
    <title>Common and specific properties</title>

    <informaltable border="0">
      <colgroup width="40%"/>

      <colgroup width="20%"/>

      <colgroup width="40%"/>

      <tr>
        <th align="center" colspan="3" valign="top">Common
        <classname>Rectangle</classname> and <classname>Circle</classname>
        attributes:</th>
      </tr>

      <tr>
        <td valign="top"/>

        <td valign="top"><programlisting language="java">double x;
double y;</programlisting></td>

        <td valign="top"/>
      </tr>

      <tr>
        <th align="center" valign="top"><classname>Rectangle</classname>
        attributes</th>

        <td/>

        <th align="center" valign="top"><classname>Circle</classname>
        attributes</th>
      </tr>

      <tr>
        <td valign="top"><programlisting language="java">double width;
double height;</programlisting></td>

        <td/>

        <td valign="top"><programlisting language="java">double radius;</programlisting></td>
      </tr>
    </informaltable>
  </figure>

  <figure xml:id="sda_inherit_fig_shapeInheritPrinciple">
    <title>Basic shape inheritance</title>

    <mediaobject>
      <imageobject>
Goik Martin's avatar
Goik Martin committed
        <imagedata fileref="Fig/shapeBasicInherit.multi.svg"/>
Goik Martin's avatar
Goik Martin committed
      </imageobject>
    </mediaobject>
  </figure>

  <figure xml:id="sda_inherit_fig_intro">
    <title>Inheritance</title>

    <itemizedlist>
      <listitem>
        <para>Derived classes inherit state and behaviour.</para>
      </listitem>

      <listitem>
        <para>Refinement, specialization.</para>
      </listitem>

      <listitem>
Goik Martin's avatar
Goik Martin committed
        <para><quote>is-A</quote> relationship:</para>
Goik Martin's avatar
Goik Martin committed

        <itemizedlist>
          <listitem>
            <para>A rectangle <emphasis role="red">is a</emphasis>
            shape.</para>
Goik Martin's avatar
Goik Martin committed
          </listitem>

          <listitem>
            <para>A circle <emphasis role="red">is a</emphasis> shape.</para>
Goik Martin's avatar
Goik Martin committed
          </listitem>
        </itemizedlist>
      </listitem>
    </itemizedlist>
  </figure>

  <figure xml:id="sda_inherit_fig_shapeSimpleImplement">
    <title>Implementing <classname>Shape</classname> hierarchy</title>

    <informaltable border="0">
      <colgroup width="25%"/>

      <colgroup width="25%"/>

      <colgroup width="25%"/>

      <colgroup width="25%"/>

      <tr>
        <td valign="top"/>

Goik Martin's avatar
Goik Martin committed
        <td colspan="2" valign="top"><programlisting language="java">public class Shape {
Goik Martin's avatar
Goik Martin committed
  private double x, y;
}</programlisting></td>

        <td valign="top"/>
      </tr>

      <tr>
Goik Martin's avatar
Goik Martin committed
        <td colspan="2" valign="top"><programlisting language="java">public class Rectangle extends Shape {
Goik Martin's avatar
Goik Martin committed
  private double width;
  private double height;
}</programlisting></td>

Goik Martin's avatar
Goik Martin committed
        <td colspan="2" valign="top"><programlisting language="java">public class Circle extends Shape {
Goik Martin's avatar
Goik Martin committed
  private double radius;
}</programlisting></td>
      </tr>
    </informaltable>
  </figure>

  <figure xml:id="sda_inherit_fig_createShapesInstances">
    <title>Creating instances</title>

    <programlisting language="java">final double x = 2, y = 3;
final Shape shape = new Shape(x, y);

final double width = 2, height = 5;
final Rectangle r = new Rectangle(x, y , width, height);

final double radius = 2.5;
final Circle circle = new Circle(x, y , radius);</programlisting>
  </figure>

  <figure xml:id="sda_inherit_fig_createShapesConstruct">
    <title><classname>Shape</classname> constructor</title>

    <programlisting language="java">/**
  * Creating a shape located at center coordinate.
  * @param x The center's x component.
  * @param y The center's y component.
  */
public Shape(double x,double y) {
  this.x = x;
  this.y = y;
}</programlisting>
  </figure>

  <figure xml:id="sda_inherit_fig_createRectangle">
    <title>Creating <classname>Rectangle</classname> instances</title>

    <programlisting language="java">final Rectangle r = 
   new Rectangle(x, y <co linkends="sda_inherit_fig_createRectangle-1"
        xml:id="sda_inherit_fig_createRectangle-1-co"/>,
                 width, height <co
        linkends="sda_inherit_fig_createRectangle-2"
        xml:id="sda_inherit_fig_createRectangle-2-co"/>);</programlisting>

    <calloutlist>
      <callout arearefs="sda_inherit_fig_createRectangle-1-co"
               xml:id="sda_inherit_fig_createRectangle-1">
        <para>Center coordinate components <quote>belonging</quote> to
        superclass <classname>Shape</classname>.</para>
      </callout>

      <callout arearefs="sda_inherit_fig_createRectangle-2-co"
               xml:id="sda_inherit_fig_createRectangle-2">
        <para>width and height <quote>belonging</quote> to class
        <classname>Rectangle</classname>.</para>
      </callout>
    </calloutlist>

    <para>Solution: Nested constructor call. Coming soon ...</para>
  </figure>

  <figure xml:id="sda_inherit_fig_RectangleConstructor">
    <title><classname>Rectangle</classname> constructor</title>

    <programlisting language="java">/**
  * Creating a rectangle at (x|y) of given width and height.
  * @param x Center's x component.
  * @param y Center's y component.
  * @param width Rectangle's width.
  * @param height Rectangle's height.
  */
public <link
        xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/blob/master/P/Sd1/Figure/ToString/src/main/java/de/hdm_stuttgart/mi/sd1/shape/model/Rectangle.java">Rectangle</link>(double x, double y,
             double width, double height) {
  super(x, y) <co linkends="sda_inherit_fig_RectangleConstructor-1"
        xml:id="sda_inherit_fig_RectangleConstructor-1-co"/>;
  this.width = width; this.height = height <co
        linkends="sda_inherit_fig_RectangleConstructor-2"
        xml:id="sda_inherit_fig_RectangleConstructor-2-co"/>;
}</programlisting>

    <calloutlist role="slideExclude">
      <callout arearefs="sda_inherit_fig_RectangleConstructor-1-co"
               xml:id="sda_inherit_fig_RectangleConstructor-1">
        <para>Passing center coordinate to superclass
        <classname>Shape</classname>'s constructor.</para>

        <note>
          <para>This <emphasis>must</emphasis> be the first statement within
          <classname>Rectangle</classname>'s constructor.</para>
        </note>
      </callout>

      <callout arearefs="sda_inherit_fig_RectangleConstructor-2-co"
               xml:id="sda_inherit_fig_RectangleConstructor-2">
        <para>Processing <code language="java">width</code> and <code
Goik Martin's avatar
Goik Martin committed
        language="java">height</code> in <quote>current</quote>
        <classname>Rectangle</classname> constructor.</para>
      </callout>
    </calloutlist>
  </figure>

  <section xml:id="sd1_inherit_sect_overrideEquals">
    <title>Overriding <methodname>equals()</methodname> and
    <methodname>hashCode()</methodname></title>

    <figure xml:id="sda_inherit_fig_ShapeEquals">
      <title><classname>Shape</classname>.<methodname>equals()</methodname></title>

      <programlisting language="java">public abstract class Shape {
  ...
  @Override <co linkends="sda_inherit_fig_ShapeEquals-1"
          xml:id="sda_inherit_fig_ShapeEquals-1-co"/> public boolean equals(final Object o) {
    if (o instanceof Shape <emphasis role="red">s</emphasis> <co
          linkends="sda_inherit_fig_ShapeEquals-2"
          xml:id="sda_inherit_fig_ShapeEquals-2-co"/>) { 
      return x == <emphasis role="red">s</emphasis>.x &amp;&amp; y == <emphasis
          role="red">s</emphasis>.y; <co
          linkends="sda_inherit_fig_ShapeEquals-4"
          xml:id="sda_inherit_fig_ShapeEquals-4-co"/>
    } else {
      return false; <co linkends="sda_inherit_fig_ShapeEquals-5"
          xml:id="sda_inherit_fig_ShapeEquals-5-co"/>
    } ...</programlisting>

      <calloutlist role="slideExclude">
        <callout arearefs="sda_inherit_fig_ShapeEquals-1-co"
                 xml:id="sda_inherit_fig_ShapeEquals-1">
          <para>Promise: The current method overrides a superclass
          method.</para>
        </callout>

        <callout arearefs="sda_inherit_fig_ShapeEquals-2-co"
                 xml:id="sda_inherit_fig_ShapeEquals-2">
          <para>Other instance is a <classname>Shape</classname>
          object?</para>
        </callout>

        <callout arearefs="sda_inherit_fig_ShapeEquals-4-co"
                 xml:id="sda_inherit_fig_ShapeEquals-4">
          <para>Return <code language="java">true</code> if and only if both
          center coordinate pairs are equal.</para>
        </callout>

        <callout arearefs="sda_inherit_fig_ShapeEquals-5-co"
                 xml:id="sda_inherit_fig_ShapeEquals-5">
          <para>Other object distinct from class
          <classname>Shape</classname>.</para>
        </callout>
      </calloutlist>
    </figure>

    <figure xml:id="sda_inherit_fig_RectangleEquals">
      <title><classname>Rectangle</classname>.<methodname>equals()</methodname></title>

      <programlisting language="java">public class Rectangle extends Shape {
  ...
  @Override public boolean equals(final Object o) {
    if (o instanceof Rectangle <emphasis role="red">r</emphasis>) {
      return super.equals(o) <co linkends="sda_inherit_fig_RectangleEquals-1"
          xml:id="sda_inherit_fig_RectangleEquals-1-co"/> &amp;&amp;
Goik Martin's avatar
Goik Martin committed
             width == <emphasis role="red">r</emphasis>.width &amp;&amp; height == <emphasis
          role="red">r</emphasis>.height <co
          linkends="sda_inherit_fig_RectangleEquals-2"
          xml:id="sda_inherit_fig_RectangleEquals-2-co"/>;
    } else {
      return false;
    } ...</programlisting>

      <calloutlist role="slideExclude">
        <callout arearefs="sda_inherit_fig_RectangleEquals-1-co"
                 xml:id="sda_inherit_fig_RectangleEquals-1">
          <para>Including superclass method
          <classname>Shape</classname>.<methodname>equals()</methodname>.</para>
        </callout>

        <callout arearefs="sda_inherit_fig_RectangleEquals-2-co"
                 xml:id="sda_inherit_fig_RectangleEquals-2">
          <para>Return <code language="java">true</code> if and only if both
          <code language="java">width</code> and <code
          language="java">height</code> pairs are equal.</para>
        </callout>
      </calloutlist>
    </figure>

    <qandaset defaultlabel="qanda" xml:id="sd1_qanda_stringEqualProblem">
      <title>Let me pass, please!</title>

      <qandadiv>
        <qandaentry>
          <question>
            <para>Consider the following snippet:</para>

            <programlisting language="java">final Scanner scan = new Scanner(System.in));
do {
  System.out.print("Please enter password: ");
  final String password = scan.nextLine();
  if (password == "secret") {
    break;  // Leave enclosing do ... while loop
  } else {
    System.out.println("Sorry, please try again");
  }
} while (true);
  System.out.println("You made it!");
  // ...</programlisting>

            <para>Describe the above code's intended behaviour. Will it
            succeed? Execute the above code and provide a clue for correcting
            the underlying flaw.</para>
          </question>

          <answer>
            <para>The user is being asked for a password. Only when entering
            <code>"secret"</code> access shall be granted.</para>

            <para>Unfortunately comparing the user's input and the
            corresponding password is seriously flawed:</para>

            <programlisting language="java">...
  if (password == "secret")
...</programlisting>

            <para>On execution the string literal "secret" will be represented
Goik Martin's avatar
Goik Martin committed
            as a <classname xlink:href="javaapi://String">String</classname>
            object in memory. Each new user input string will be represented
            as a <emphasis>different</emphasis> <classname
Goik Martin's avatar
Goik Martin committed
            xlink:href="javaapi://String">String</classname> object in memory
            as well.</para>
            <para>Unfortunately the <quote>==</quote> operator only works as
            expected for the eight built in primitive <xref
            linkend="glo_Java"/> types. With respect to class instances
            variables hold references to objects rather than to the objects'
            values. The <quote>==</quote> operator compares for object
            identity rather than for object equality.</para>

            <para>Two different <classname
Goik Martin's avatar
Goik Martin committed
            xlink:href="javaapi://String">String</classname> instances may off
            course be equal with respect to their <quote>payload</quote>
            namely the values they both represent. Comparing for object
            equality rather than for object identity in <xref
            linkend="glo_Java"/> requires using the
            <methodname>equals(...)</methodname> method instead. A
            prerequisite for this to work requires the class authors
            overriding the <methodname
            xlink:href="javaapi://Object#equals(java.lang.Object)">Object.equals(Object
            o)</methodname> method accordingly. This override does exist in
Goik Martin's avatar
Goik Martin committed
            class <classname xlink:href="javaapi://String">String</classname>.
            Within the given context we may thus simply use <methodname
            xlink:href="javaapi://String#equals(java.lang.Object)">String.equals(Object
            o)</methodname>:</para>

            <programlisting language="none">final Scanner scan = new Scanner(System.in));
do {
  System.out.print("Please enter password: ");
  final String password = scan.nextLine();
  <emphasis role="red">if (password.equals("secret"))</emphasis> {
    break;  // Leave enclosing do ... while loop
  } else {
    System.out.println("Sorry, please try again");
  }
} while (true);
System.out.println("You made it!");
// ...</programlisting>
          </answer>
        </qandaentry>
      </qandadiv>
    </qandaset>

    <qandaset defaultlabel="qanda" xml:id="sd1_qanda_enomNoEqualsRequired">
Goik Martin's avatar
Goik Martin committed
      <title>Why is == correctly comparing <code language="java">enum</code>
      instances?</title>

      <qandadiv>
        <qandaentry>
          <question>
            <para>The preceding exercise <xref
            linkend="sd1_qanda_stringEqualProblem"/> told us to override
            <methodname
            xlink:href="javaapi://Object#equals(java.lang.Object)">Object.equals(Object
Goik Martin's avatar
Goik Martin committed
            o)</methodname> when comparing different objects for equality. The
Goik Martin's avatar
Goik Martin committed
            == operator on the other hand does compare for object identity
            rather than semantic equality of objects based on their respective
            attribute values. However comparing <code
            language="java">Enum</code> instances for equality using the <code
            language="java">==</code> operator seems to be sufficient<abbrev>
            e.g.</abbrev>:</para>

            <programlisting language="java">Day day = Day.Saturday;

// Sufficient using operator == ?
if (day == Day.FRIDAY) ... 

// Or do we require equals?
if (day.equals(Day.FRIDAY)) ...</programlisting>

            <para>Do we thus require an <methodname>equals(Object
Goik Martin's avatar
Goik Martin committed
            o)</methodname> method in <code language="java">enum</code>
            <classname>Day</classname> for comparisons? Give a precise
            explanation.</para>
          </question>

          <answer>
            <para>In case of <code language="java">enum</code> instances using
            the <quote>==</quote> operator is sufficient. Due to the way <code
            language="java">enum</code>'s are being constructed instance
Goik Martin's avatar
Goik Martin committed
            creation is limited to the underlying <code
Goik Martin's avatar
Goik Martin committed
            language="java">enum</code>'s scope by its implicitly <code
Goik Martin's avatar
Goik Martin committed
            language="java">private</code> constructor. It is thus impossible
            creating new instances outside the respective <code
Goik Martin's avatar
Goik Martin committed
            language="java">enum</code>'s scope.</para>

Goik Martin's avatar
Goik Martin committed
            <para>Therefore for any two given <code
            language="java">enum</code> instances both object identity and
            equality of their respective values is being guaranteed to yield
            the very same result:</para>
Goik Martin's avatar
Goik Martin committed
            <programlisting language="none">MyEnum instance1 = MyEnum.x,                      // MyEnum representing
       instance2 = MyEnum.y;                      // some enum type.
Goik Martin's avatar
Goik Martin committed
  <emphasis role="red">objectIdentity</emphasis> = (instance1 == instance2),        // Both boolean values will
  <emphasis role="red">objectEquality</emphasis> = instance1.equals(instance2);     // always be equal.</programlisting>
Goik Martin's avatar
Goik Martin committed
            <para>As an aside: In case of <code language="java">null</code>
            values using the <quote>==</quote> operator avoids
            <classname>java.lang.NullPointerException</classname>
            problems:</para>

            <programlisting language="java">Day day = null;

if (day == Day.FRIDAY) ...      // Just different, no problems

if (day.equals(Day.FRIDAY)) ... // Oops: NPE approaching ...</programlisting>
          </answer>
        </qandaentry>
      </qandadiv>
    </qandaset>
  </section>

  <section xml:id="sd1_inherit_sect_overrideToString">
Goik Martin's avatar
Goik Martin committed
    <title>Overriding toString()</title>
Goik Martin's avatar
Goik Martin committed
    <figure xml:id="sda_inherit_fig_shapeInstanceLog">
      <title>Printing a <classname>Shape</classname>'s info</title>
Goik Martin's avatar
Goik Martin committed
      <informaltable border="0">
        <tr>
          <th>Code</th>
Goik Martin's avatar
Goik Martin committed
          <th>Output</th>
        </tr>
Goik Martin's avatar
Goik Martin committed
        <tr>
          <td valign="top"><programlisting language="none">package inherit;
Goik Martin's avatar
Goik Martin committed
public class Run {
  
  public static void main(String[] args) {
Goik Martin's avatar
Goik Martin committed
  final Shape shape =
Goik Martin's avatar
Goik Martin committed
     new Shape(<emphasis role="red">2.0</emphasis>, <emphasis role="red">3.0</emphasis>); // Center coordinates
Goik Martin's avatar
Goik Martin committed
    System.out.println(shape); </programlisting></td>

          <td valign="top"><screen>inherit.Shape@37d31475</screen><para>Desired:</para><screen><emphasis
                role="red">(2.0|3.0)</emphasis></screen></td>
        </tr>
      </informaltable>
Goik Martin's avatar
Goik Martin committed
    </figure>
Goik Martin's avatar
Goik Martin committed
    <figure xml:id="sda_inherit_fig_shapeToStringRedefine">
      <title>Overwriting <methodname
      xlink:href="javaapi://Object#toString--">toString()</methodname></title>
Goik Martin's avatar
Goik Martin committed
      <mediaobject>
        <imageobject>
Goik Martin's avatar
Goik Martin committed
          <imagedata fileref="Fig/shapeOverrideToStringIde.multi.svg"/>
Goik Martin's avatar
Goik Martin committed
        </imageobject>
      </mediaobject>
    </figure>

    <figure xml:id="sda_inherit_fig_shapeExtendObject">
      <title><classname>Shape</classname> extending
      <classname>Object</classname></title>

      <mediaobject>
        <imageobject>
Goik Martin's avatar
Goik Martin committed
          <imagedata fileref="Fig/shapeRedefineToString.multi.svg"/>
Goik Martin's avatar
Goik Martin committed
        </imageobject>
      </mediaobject>
    </figure>

    <figure xml:id="sda_inherit_fig_RectangleLogging">
      <title>Logging <classname>Rectangle</classname> instances</title>
Goik Martin's avatar
Goik Martin committed
      <informaltable border="0">
        <tr>
          <th>Code</th>
Goik Martin's avatar
Goik Martin committed
          <th>Output</th>
        </tr>
Goik Martin's avatar
Goik Martin committed
        <tr>
          <td valign="top"><programlisting language="java">final Rectangle r =                   // Center coordinates,
  new Rectangle(2.0, 3.0, 3.0, 4.0);  // width and height
System.out.println(r);</programlisting></td>
Goik Martin's avatar
Goik Martin committed
          <td valign="top"><screen>(2.0|3.0)</screen><para>Desired:</para><screen><emphasis
                role="red">Rectangle at </emphasis>(2.0|3.0)<emphasis
                role="red">, width= 3.0, height=4.0</emphasis></screen></td>
        </tr>
      </informaltable>
Goik Martin's avatar
Goik Martin committed
    </figure>

    <figure xml:id="sda_inherit_fig_RectangleOverrideToStringAgain">
Goik Martin's avatar
Goik Martin committed
      <title>Override <methodname>toString()</methodname> in class
      <classname>Rectangle</classname>.</title>
Goik Martin's avatar
Goik Martin committed

      <programlisting language="java">public class Rectangle extends Shape {
  @Override public String toString() {
Goik Martin's avatar
Goik Martin committed
    return "<emphasis role="red">Rectangle at </emphasis>" + super.toString() <co
Goik Martin's avatar
Goik Martin committed
          linkends="sda_inherit_fig_RectangleOverrideToStringAgain-1"
          xml:id="sda_inherit_fig_RectangleOverrideToStringAgain-1-co"/> +
Goik Martin's avatar
Goik Martin committed
      "<emphasis role="red">, width= </emphasis>" + <emphasis role="red">width</emphasis> + "<emphasis
          role="red">, height=</emphasis>" + <emphasis role="red">height</emphasis>; <co
Goik Martin's avatar
Goik Martin committed
          linkends="sda_inherit_fig_RectangleOverrideToStringAgain-2"
          xml:id="sda_inherit_fig_RectangleOverrideToStringAgain-2-co"/>
  } ...</programlisting>

      <calloutlist>
        <callout arearefs="sda_inherit_fig_RectangleOverrideToStringAgain-1-co"
                 xml:id="sda_inherit_fig_RectangleOverrideToStringAgain-1">
          <para>The <code language="java"
          xlink:href="https://docs.oracle.com/javase/tutorial/java/IandI/super.html">super</code>
Goik Martin's avatar
Goik Martin committed
          keyword allows for calling the superclass
          <classname>Shape</classname>'s <methodname>toString()</methodname>
          method inserting the (2.0|3.0) center coordinate.</para>
Goik Martin's avatar
Goik Martin committed
        </callout>

        <callout arearefs="sda_inherit_fig_RectangleOverrideToStringAgain-2-co"
                 xml:id="sda_inherit_fig_RectangleOverrideToStringAgain-2">
          <para>Append class <classname>Rectangle</classname>'s
          <quote>own</quote> <code language="java">width</code> and <code
Goik Martin's avatar
Goik Martin committed
          language="java">height</code> attribute values.</para>
Goik Martin's avatar
Goik Martin committed
        </callout>
      </calloutlist>
    </figure>

    <figure xml:id="sda_inherit_fig_rectangleExtendShapa">
      <title><classname>Rectangle</classname> extending
      <classname>Shape</classname></title>
Goik Martin's avatar
Goik Martin committed

      <mediaobject>
        <imageobject>
Goik Martin's avatar
Goik Martin committed
          <imagedata fileref="Fig/rectangleRedefineToString.multi.svg"/>
Goik Martin's avatar
Goik Martin committed
        </imageobject>
      </mediaobject>
    </figure>

    <figure xml:id="sda_inherit_fig_CircleComplete">
Goik Martin's avatar
Goik Martin committed
      <title>Implementing
      <classname>Circle</classname>.<methodname>toString()</methodname></title>
Goik Martin's avatar
Goik Martin committed

      <programlisting language="java">public class Circle extends Shape {
  /**
   * Creating a circle of given center and radius
   * @param x Center's x component.
   * @param y Center's y component.
   * @param radius The circle's radius.
   */
  public Circle(double x,double y, double radius) {
    super(x, y);
    this.radius = radius;
  }
  @Override public String toString() {
    return "Circle at " + super.toString() +", radius= " + radius;
  }
  private double radius;
}</programlisting>
    </figure>
Goik Martin's avatar
Goik Martin committed
    <figure xml:id="sda_inherit_fig_shapeToString">
      <title><classname>Shape</classname> and
      <methodname>toString()</methodname></title>
Goik Martin's avatar
Goik Martin committed
      <mediaobject>
        <imageobject>
Goik Martin's avatar
Goik Martin committed
          <imagedata fileref="Fig/shapeToString.svg"/>
Goik Martin's avatar
Goik Martin committed
        </imageobject>
      </mediaobject>
    </figure>

    <qandaset defaultlabel="qanda"
              xml:id="sd1_quanda_inherit_StringBufferNoEqualMethod">
      <title><classname>String</classname> vs.
      <classname>StringBuffer</classname></title>

      <qandadiv>
        <qandaentry>
          <question>
            <para>Consider two <classname
            xlink:href="javaapi://StringBuffer">StringBuffer</classname>
            instances:</para>

            <informaltable border="1">
              <colgroup width="54%"/>

              <colgroup width="46%"/>

              <tr>
                <th>Code</th>

                <th>Execution result</th>
              </tr>

              <tr>
                <td valign="top"><programlisting language="java">final <link
                      xlink:href="javaapi://StringBuffer">StringBuffer</link>
  a = new StringBuffer("test"),
  b = new StringBuffer("test");

System.out.println(a.equals(b));</programlisting></td>

                <td valign="top"><screen>false</screen></td>
              </tr>
            </informaltable>

            <para>Strangely instances of String behave differently:</para>

            <informaltable border="1">
              <colgroup width="54%"/>

              <colgroup width="46%"/>

              <tr>
                <th>Code</th>

                <th>Execution result</th>
              </tr>

              <tr>
                <td valign="top"><programlisting language="java">final String
  a = new String("test"),
  b = new String("test");

System.out.println(a.equals(b));</programlisting></td>

                <td valign="top"><screen>true</screen></td>
              </tr>
            </informaltable>

            <para>Explain this different behaviour.</para>

            <tip>
              <para>Take a closer look at the <classname
Goik Martin's avatar
Goik Martin committed
              xlink:href="javaapi://String">String</classname> and <classname
              xlink:href="javaapi://StringBuffer">StringBuffer</classname>
              <xref linkend="glo_API"/> regarding the
              <methodname>toString()</methodname> method.</para>
            </tip>
          </question>

          <answer>
            <para>The <classname
Goik Martin's avatar
Goik Martin committed
            xlink:href="javaapi://String">String</classname> <xref
            linkend="glo_API"/> reveals:</para>

            <screen>public boolean equals (Object anObject)
Compares this string to the specified object. The result is true if and only if the argument is
not null and is a String object that represents the same sequence of characters as this object.

Overrides: equals in class Object

Parameters:
anObject - The object to compare this String against

Returns:
true if the given object represents a String equivalent to this string, false otherwise</screen>

            <para>In a nutshell: Two instances of String will be compared for
            equality character by character. The superclass <classname
            xlink:href="javaapi://Object">Object</classname>.<methodname
            xlink:href="javaapi://Object#equals(java.lang.Object)">equals()</methodname>
            method is being overridden.</para>

            <para>In class <classname
Goik Martin's avatar
Goik Martin committed
            xlink:href="javaapi://StringBuffer">StringBuffer</classname> we do
            not find any <methodname>equals()</methodname> method. Thus
            <classname
            xlink:href="javaapi://Object">Object</classname>.<methodname
            xlink:href="javaapi://Object#equals(java.lang.Object)">equals()</methodname>
            is not being overridden. When comparing two instances of
            <classname
            xlink:href="javaapi://StringBuffer">StringBuffer</classname>
            effectively <classname
            xlink:href="javaapi://Object">Object</classname>.<methodname
            xlink:href="javaapi://Object#equals(java.lang.Object)">equals()</methodname>
            will be executed. Its <xref linkend="glo_API"/> reveals:</para>

            <screen>public boolean equals (Object obj)
Indicates whether some other object is "equal to" this one.
...
Parameters:
obj - the reference object with which to compare.
Returns:
true <emphasis role="red">if this object is the same as the obj argument</emphasis>; false otherwise.</screen>

            <para>Thus two instances of <classname
Goik Martin's avatar
Goik Martin committed
            xlink:href="javaapi://StringBuffer">StringBuffer</classname> will
            be compared for object identity rather than representing the same
            string value.</para>
          </answer>
        </qandaentry>
      </qandadiv>
    </qandaset>
Goik Martin's avatar
Goik Martin committed

    <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="javaapi://Enum#ordinal()">ordinal()</methodname>.</para>
Goik Martin's avatar
Goik Martin committed
          </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>
Goik Martin's avatar
Goik Martin committed
  </section>

  <section xml:id="sd1_inherit_sect_final">
    <title><code language="java">final</code> methods</title>

    <figure xml:id="sda_inherit_fig_moveRectangle">
      <title>Moving <classname>Shape</classname> instances</title>

      <mediaobject>
        <imageobject>
Goik Martin's avatar
Goik Martin committed
          <imagedata fileref="Fig/rectangleTranslate.multi.svg"/>
Goik Martin's avatar
Goik Martin committed
        </imageobject>
      </mediaobject>
    </figure>

    <figure xml:id="sda_inherit_fig_shapeMove">
Goik Martin's avatar
Goik Martin committed
      <title>Implementing <classname>Shape</classname> movements</title>
Goik Martin's avatar
Goik Martin committed

      <programlisting language="java">public class Shape {
  /**
   * Move by a given translation vector
   * @param xTrans Translation's x component
   * @param yTrans Translation's y component
   */
  public void move(final int xTrans, final int yTrans) {
    x += xTrans;
    y += yTrans;
  } ...</programlisting>
    </figure>

    <figure xml:id="sda_inherit_fig_shapeMoveProblemSubclass">
      <title>Fools are everywhere!</title>

      <programlisting language="java">public class Rectangle extends Shape {
  @Override public void move(int xTrans, int yTrans) {
    // I'm so dumb!
Goik Martin's avatar
Goik Martin committed
    ...
Goik Martin's avatar
Goik Martin committed
  }</programlisting>
Goik Martin's avatar
Goik Martin committed
    </figure>
Goik Martin's avatar
Goik Martin committed
    <figure xml:id="sda_inherit_fig_shapeMoveProblemSubclassSolution">
      <title>Solution: <emphasis role="red">final</emphasis> prevents
      overriding</title>
Goik Martin's avatar
Goik Martin committed
      <programlisting language="none">public abstract class Shape {
... public <emphasis role="red">final</emphasis> void move(final int xTrans, final int yTrans) {
      x += xTrans;
      y += yTrans;
    }...</programlisting>

      <programlisting language="java">public class Rectangle extends Shape {
  // Syntax error: 'move(int, int)' cannot override
  // 'move(int, int)' in 'inherit.Shape'; overridden method is final
  @Override public void move(int xTrans, int yTrans) {...</programlisting>
Goik Martin's avatar
Goik Martin committed
    </figure>
  </section>

  <section xml:id="sd1_inherit_sect_abstractMethods">
    <title>Abstract methods</title>

    <figure xml:id="sda_inherit_fig_subclassImplementGetArea">
      <title>Calculating a shape's area</title>

      <informaltable border="0">
        <tr>
Goik Martin's avatar
Goik Martin committed
          <td valign="top"><programlisting language="java">public class Rectangle extents Shape {
Goik Martin's avatar
Goik Martin committed
  /**
Goik Martin's avatar
Goik Martin committed
   * Calculate the area.
Goik Martin's avatar
Goik Martin committed
   * @return The rectangle's area
Goik Martin's avatar
Goik Martin committed
   */
  public double getArea() {
    return width * height;
  } ...</programlisting></td>
Goik Martin's avatar
Goik Martin committed
          <td valign="top"><programlisting language="java">public class Circle extents Shape {
  /**
Goik Martin's avatar
Goik Martin committed
   * Calculate the area.
   * @return The circle's area
   */
  public double getArea() {
    return PI * radius * radius;
  } ...</programlisting></td>
Goik Martin's avatar
Goik Martin committed
        </tr>
      </informaltable>
    </figure>

    <figure xml:id="sda_inherit_fig_shapePolymorphicAreaCall">
Goik Martin's avatar
Goik Martin committed
      <title>Desired: Polymorphic <methodname>getArea()</methodname>