<p><strong>Types</strong>
All interfaces and classes are types.  All
variabes in Java must have a type.</p>

<p>The type of a variable determines what methods
are visible.  This is the 
<em>visibility principle</em>.</p>

<p>When a method call is communicated  via
a variable, the "pointee" is responsible for
executing the method.  This is the 
<em>delegation principle</em>, so-called because
the job of executing the code is delegated to the 
pointee.  </p>

<p>Types in Java are organized into a hierarchy.  
All classes automatically inherit from the root
class 
<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html"><code>java.lang.Object</code></a>.</p>

<p>This is why any class you create automaticaly has
the methods <code>toString()</code> and <code>equals</code>.
</p>

<h2><code>final</code> Again</h2>

<p>The <code>final</code> keyword can appear in two 
contexts in inheritance.</p>

<ul>
    <li>If a class is marked <code>final</code>, it cannot
    be extended.  The class <code>String</code> and the 
    wrapper classes are all final classes.</li>
    <li>If a method in a class is marked <code>final</code>,
    it cannot be overrriden by a descendant class</li>
</ul>

<p>Both of these stipuations are enforced at compile time.
<a href="https://www.whitman.edu/mathematics/java_tutorial/java/javaOO/final.html">This article</a> supplies a security rationale
for making the String class final.</p>
</main>

<h2>Abstract Classes</h2>
<h2>Functional Interfaces</h2>