Friday, July 2, 2021

Independence Day Adams Post (Stewart Chapter 16: The Cosmic Egg)

Table of Contents

1. Introduction
2. A Rapoport Problem
3. Calculating the Cosmos Chapter 16: The Cosmic Egg
4. Lemay Lesson 16: Packages and Interfaces
5. My Own Interface in Java
6. Conclusion

Introduction

Today is July 2nd, two days before the Independence Day holiday. I often refer to two days before a holiday as an "Adam" (as in "Christmas Adam," December 23rd), since it's the day before an Eve. But in the case of Independence Day, we ought to call it "Adams" -- as in President John Adams, who suggested that the second, not the Fourth of July, become our national day:

"“The Second Day of July 1776, will be the most memorable Epocha, in the History of America. I am apt to believe that it will be celebrated, by succeeding Generations, as the great anniversary Festival. It ought to be commemorated, as the Day of Deliverance by solemn Acts of Devotion to God Almighty."

-- John Adams

Therefore today is Independence Day Adams -- that is, Independence Day according to Adams. (It's believed that the Continental Congress voted for independence on the second, but didn't actually adopt the Declaration until the fourth, hence the two-day discrepancy.

By the way, notice that this is not Independence Day Observed. Since the Fourth of July is on a Sunday, the federal holiday is observed on Monday, the fifth.

A Rapoport Problem

Today on her Daily Epsilon on Math 2021, Rebecca Rapoport writes:

Find the ratio of w to v.

(Here is the given info from the diagram -- the three medians of a triangle are drawn in, intersecting at the point we know as the centroid. Then w is the length from a vertex to the centroid, while v is the length from the centroid to the side along the median.)

At last -- it's an actual Geometry problem on a blogging day!

This problem is all about the centroid -- one of the three points of concurrency that don't appear in the U of Chicago text, yet appears in the Common Core standards.

By the way, I wrote more about centroids during the first two years of this blog, before I started working at the old charter school. I knew that it was a topic that appeared on the SBAC but not the U of Chicago text, so I wanted to blog about it. In fact, back when I was a math tutor six years ago, I tutored a student who had the Glencoe text, and there was a brief mention of the answer. Let me reblog what I wrote back then:

First of all, I showed my student the two triangles that I mentioned in the previous post, and asked him to locate the circumcenter, orthocenter, and centroid of each. This time, he had a much easier time calculating these three centers. I'm actually surprised that our simple formula for the centroid given the coordinates does not appear in Glencoe. Instead, the text only states that the centroid is 2/3 of the way along each median, from the vertex to the opposing side. This makes sense in synthetic geometry, but not in coordinate geometry -- unless one is prepared to use the Distance Formula to figure out what 2/3 of each distance is.

Returning to the present, we don't know what exactly w and v are, but all we need is the ratio. So we might as well assume that the length of a median is 1, so that w = 2/3 and v = 1/3. Then the ratio we seek is 2/3:1/3 = 2:1. Therefore the desired ratio is 2 -- and of course, today's date is the second.

I also wrote up an old lesson five years ago that gives a full proof of this statement. That day, I gave proofs in both coordinate and synthetic geometry. (Notice that I proved some preliminary results, and I also used a third text, published by HMH, to complete the proofs.)

There are several theorems to prove beforehand. First, we must prove the Midpoint Formula -- and we must do so without using the Slope or Distance Formulas. We wish to calculate the midpoint of the segment whose endpoints are (ab) and (cd).

We begin with a right triangle without coordinates. Let's take the perpendicular bisector of one of its legs -- since this is a right triangle, this leg is perpendicular to the other leg. So we have two lines perpendicular to the first leg -- its perpendicular bisector and the other leg. Thus by the Two Perpendiculars Theorem, the perpendicular bisector of one leg is parallel to the other leg.

But notice that by the Midpoint Connector Theorem (which we already proved on the blog), the line joining the midpoints of two sides of a triangle is parallel to the third side. So the line joining the midpoints of one leg and the hypotenuse of the triangle is parallel to the other leg.

This means that we have two lines, each passing through the midpoint of the first leg, that are parallel to the second leg -- the perpendicular bisector and the midpoint. But by Playfair, there is only one line passing through the midpoint of the first leg and parallel to the second. Thus the perpendicular bisector and the midpoint connector are really the same line -- that is, the perpendicular bisector of the first leg passes through the midpoint of the hypotenuse.

Of course, it didn't matter which leg we started with above. The conclusion is that the perpendicular bisectors of both legs pass through the midpoint of the hypotenuse. And of course, the perpendicular bisector of the hypotenuse trivially passes through its own midpoint. So all three perpendicular bisectors pass through the midpoint of the hypotenuse -- that is, the midpoint of the hypotenuse is the circumcenter of the right triangle! (I know, it's strange for me to start talking about circumcenters when we're supposed to be finding the centroid, but bear with me.)

Once we have this result, we can find the midpoint of the segment from (ab) to (cd) as follows. We set up a right triangle whose vertices are (ab), (ad), and (cd). (This is the same trick that we use to derive the Distance Formula.) The perpendicular bisector of the base is halfway between the lines x = a and x = c, so it's x = (a + c) / 2, and the perpendicular bisector of the height is halfway between the lines y = b and y = d, so it's y = (b + d) / 2. Then the midpoint of the hypotenuse (which goes from (ab) to (cd)) is where those perpendicular bisectors intersect -- ((a + c) / 2, (b + d) / 2).

Now we can calculate the centroid of any triangle -- but we're going to follow a trick established in the Houghton Mifflin Harcourt Integrated Math I text. We will choose vertices for the triangle so that two of the medians turn out to be parallel to the axes. Here's an example of such a triangle (inspired by one of the triangles I placed on last week's Euler Line worksheet): A(16, 16), B(0, 0), C(8, 32). We see that the midpoint of AB is (8, 8), and since C is (8, 32), the median from C is x = 8. And the midpoint of BC is (4, 16), and since A is (16, 16), the median from A is y = 16. So the centroid must have the coordinates (8, 16). Notice that is this case, finding the median from B isn't too terrible -- the midpoint of AC is (12, 24) and B is (0, 0), so the equation of the median is y = 2x. But it's much easier to use the medians from A and C.

But you may notice that the Euler Line worksheet gives a different method to find the centroid -- simply take the average of all of the coordinates. Notice that this method works for the triangle we gave above -- ((16 + 0 + 8) / 3), (16 + 0 + 32) / 3) = (8, 16). So now we might wonder, why doesn't the HMH text simply give that formula rather than force us to find the equations of two medians?

I suspect it's because that formula simply hasn't been proved yet. The proof of the general formula for the centroid requires some rather nasty algebra, and so we don't prove it. So in order to avoid mentioning formulas before proving them, we just skip the formula altogether.

So now you ask, why did I set up the Euler line worksheet the way that I did? Recall that all of those worksheets were set up mostly for the benefit of the student I was tutoring. My student was working out of a different text -- the Glencoe text -- and that text asked him to calculate centroids when none (or at most one) of the medians were parallel to the axes. I don't recall how the Glencoe text directed the students to find centroids, but when I saw him struggle with finding the equations of the medians and solving the system to calculate their intersection, I couldn't resist simply telling him to find the average of the coordinates.

Without providing the Centroid Formula, it's difficult to give a simple example to calculate the full Euler line. To make the median easy to find, we need to choose a triangle with a horizontal median and a vertical median. This will never be a triangle whose circumcenter is easy to find -- a right triangle with a horizontal side and a vertical side. So we can never have a triangle where all three centers on the Euler line are easy to calculate.

Well, at least I can provide the proof of the Centroid Theorem, as I gave five years ago:

Median Concurrency Theorem:
The three medians of a triangle meet at a point G, called the centroid of the triangle. On each median, the distance of G to the vertex is twice the distance of G to the midpoint of the opposite side.

Given: In triangle ABC, C', B', and A' are midpoints of AB, AC, and BC respectively.
(This way, the medians are AA', BB', and CC' as per Wu's notation.)
Prove: CC' meets BB' at a point G such that BG = 2GB'.
(Without loss of generality, the same proof will work if we change B or C to A.)

Proof:
Statements                                                      Reasons
1. bla, bla, bla                                                1. Given
2. C'B' | | BC, C'B' = 1/2 BC                          2. Midpoint Connector Theorem (ABC)
3. Let M, N be midpoints of BG, CG            3. Ruler Postulate (Point-Line)
4. MN | | BC, MN = 1/2 BC                          4. Midpoint Connector Theorem (GBC)
5. C'B' | | MN                                                 5. Transitivity of Parallelism Theorem
6. C'B' = MN                                                 6. Transitive Property of Equality
7. MNB'C' is a parallelogram                        7. Sufficient Conditions (pgram test), part (d)
8. MB' and NC' bisect each other                  8. Properties (pgram consequence), part (c)
9. BM = MG, MG = GB'                               9. Definition of midpoint
10. BM = GB'                                               10. Transitive Property of Equality
11. BM + MG = GB' + GB'                          11. Addition Property of Equality
12. BG = 2GB'                                               12. Segment Addition (Betweenness)

Returning to 2021, you might ask, how come I don't post this proof these days? Well, what happened was that I worked for one year at the old charter school. Then after I left, I decided to adhere solely to the U of Chicago text. Since the Centroid Theorem isn't in that text, I ended up not posting it.

By the way, when I was a young Geometry student, it was well before Common Core, so I never learned this at all. In fact, the first time I ever saw this was in a Physics class, when the teacher was trying to explain the center of gravity (which the centroid is, for a triangle).

Calculating the Cosmos Chapter 16: The Cosmic Egg

Chapter 16 of Ian Stewart's Calculating the Cosmos is called "The Cosmic Egg." As usual, each chapter begins with a quote:

"In the beginning there was nothing, which exploded."

-- Terry Pratchett, Lords and Ladies

As this quote implies, this chapter is all about the origin of the universe. What else is out there, and where did we come from? Of these questions, Stewart writes:

"They certainly occurred no more than 4000 years ago to civilizations such as those of China, Mesopotamia, and Egypt, which left written records. Their answers were imaginative, if you think that attributing everything you don't understand to unseen deities with bizarre bodies and lifestyles counts as exercising imagination, but they were ultimately unedifying."

One scientist, Fred Hoyle, supposed that the universe has always existed. This theory is known as the steady state theory, but despite its name, something did happen to the universe:

"It's just that what did happen didn't cause any fundamental changes. Hoyle's view was that the universe gradually spreads out, gaining extra space as new particles quietly appear from nothing in the voids between the galaxies."

But a Belgian Jesuit priest, Georges Lemaitre, challenged the steady state theory with an amazing discovery -- the universe is expanding:

"Lemaitre tried to estimate the expansion rate from astronomical observations, but at that time these were too rudimentary to be convincing. An expanding universe was a difficult notion to accept if you believed the universe to be eternal and immutable."

In fact the author names this chapter "The Cosmic Egg" after Lemaitre's theory -- the Cosmic Egg exploded at the moment of creation. Of course, we now this theory as the Big Bang. Anyway, it's possible to prove that the universe is indeed expanding:

"This possibility stemmed from an unexpected discovery by Vesto Slipher and Milton Humason: the spectra of many galaxies are shifted towards the red end of the spectrum."

This redshift shows that the universe is indeed expanding. Edwin Hubble used this information to attempt again to determine the shape of the universe:

"The upshot of all this work is a standard model of the spacetime geometry of the universe, the Friedmann-Lemaitre-Robertson-Walker metric, put together in the 1930s."

Stewart tells us that this leads to paradoxical results. For example, objects more than 14.7 billion light years away appear to be moving faster than the speed of light:

"To understand why these claims make sense, we have to understand a bit more about relativity. Although it forbids matter moving faster than light, that limit is with respect to the surrounding space."

We also see that depending on how far away an object is, space appears to be expanding faster or slower between it and us -- in other words, the speed at which the object itself appears to be moving:

"That is, it increases  by 218 kilometers per second every million years into the past, so equivalently it has decreased by 218 kilometers per second for every million years after the Big Bang. We'll see in Chapter 17 that this slowdown in the expansion seems to have been reversed, so it's speeding up again, but let's not go into that right now."

Yeah -- let's get through Chapter 16 first before worrying about Chapter 17. We return to CMB, or cosmic microwave background radiation, which can be used as evidence of the Big Bang:

"Let there be light! Theory predicts that the CMB should not be exactly uniform in all directions. There ought to be very small fluctuations, estimated to be of the order of 0.001%-0.01%."

And that's exactly what the author shows us in his lone image of Chapter 16. It's the image that we promised in yesterday's post, of cosmic microwave background radiation measured by WMAP. The map shows temperature fluctuations dating from shortly after the Big Bang, seeds of irregularity that grew to create galaxies. Temperatures differ from the average by a mere 200 millionths K. He invokes Douglas Adams and asks how the universe will end:

"Not with a rock concert of cosmological proportions, which was his answer. That might be a fitting end for humanity, but perhaps not one we should inflict on any other civilization that might be out there."

Stewart speculates on several possibilities -- heat death, or a reverse Big Bang or "Big Crunch." On this note, he concludes the chapter as follows:

"Mathematics lets us explore all of these possibilities, and may one day help to decide between them. Until then, we can only speculate on the end of all things -- or not, as the case may be."

Lemay Lesson 16: Packages and Interfaces

Here is the link to today's lesson:

http://101.lv/learn/Java/ch16.htm

Lesson 16 of Laura Lemay's Teach Yourself Java in 21 Days! is called "Packages and Interfaces," and here's how it begins:

Packages and interfaces are two capabilities that allow you greater control and flexibility in designing sets of interrelated classes. Packages allow you to combine groups of classes and control which of those classes are available to the outside world; interfaces provide a way of grouping abstract method definitions and sharing them among classes that may not necessarily acquire those methods through inheritance.

Today you'll learn how to design with, use, and create your own packages and interfaces.

I mentioned this in my last post -- packages are new to me, since there's no C++ equivalent:

When you examine a new language feature, you should ask yourself two questions:

  • How can I use it to better organize the methods and classes of my Java program?
  • How can I use it while writing the actual Java code?

The first is often called programming in the large, and the second, programming in the small. Bill Joy, a founder of Sun Microsystems, likes to say that Java feels like C when programming in the small and like Smalltalk when programming in the large. What he means by that is that Java is familiar and powerful like any C-like language while you're coding individual lines, but has the extensibility and expressive power of a pure object-oriented language like Smalltalk while you're designing.

Obviously, C++ is a C-like language, but I'm not familiar with the Smalltalk language at all. OK, so now Lemay finally explains what packages are:

Packages, as mentioned a number of times in this book so far, are a way of organizing groups of classes. A package contains any number of classes that are related in purpose, in scope, or by inheritance.

Why bother with packages? If your programs are small and use a limited number of classes, you may find that you don't need to explore packages at all. But the more Java programming you do, the more classes you'll find you have. And although those classes may be individually well designed, reusable, encapsulated, and with specific interfaces to other classes, you may find the need for a bigger organizational entity that allows you to group your packages.

OK, this makes sense. And, as so often happens, we've already used packages before:

You've been using packages all along in this book. Every time you use the import command, and every time you refer to a class by its full package name (java.awt.Color, for example), you've used packages. Let's go over the specifics of how to use classes from other packages in your own programs to make sure you've got it and to go into greater depth than we have in previous lessons.

The author shows us two ways to use classes in a package:

To refer to a class in some other package, you can use its full name: the class name preceded by any package names. You do not have to import the class or the package to use it this way:

java.awt.Font f = new java.awt.Font()

OK, this is cumbersome, so let's look at the other way:

To import classes from a package, use the import command, as you've used throughout the examples in this book. You can either import an individual class, like this:

import java.util.Vector;

or you can import an entire package of classes, using an asterisk (*) to replace the individual class names:

import java.awt.*

This reminds me a little of C++, where, for example, the famous Hello World program starts with:

#include <iostream.h>

But C++ coders don't call that a "package" -- they call it a "header file" (hence the .h).

After you have imported a class or a package of classes, you can usually refer to a class name simply by its name, without the package identifier. I say "usually" because there's one case where you may have to be more explicit: when there are multiple classes with the same name from different packages.

Hmm, I'm not sure what happens in C++ if we try to #include two header files with the same class name, but I assume that it would likewise fail to compile. I do know that C++ coders often use "inclusion guards" to make sure that no class is defined twice.

Before I go on to explain how to create your own packages of classes, I'd like to make a note about how Java finds packages and classes when it's compiling and running your classes.

Java looks for those directories, in turn, inside the directories listed in your CLASSPATH variable. If you remember back to Day 1, "An Introduction to Java Programming," when you installed the JDK, you had to set up a CLASSPATH variable to point to the various places where your Java classes live. CLASSPATH usually points to the java/lib directory in your JDK release, a class directory in your development environment if you have one, perhaps some browser-specific classes, and to the current directory. When Java looks for a class you've referenced in your source, it looks for the package and class name in each of those directories and returns an error if it can't find the class file. Most "cannot load class" errors result because of missed CLASSPATH variables.

Unfortunately, I don't remember any of that -- mainly because "Day 1" was a over year ago. Now it's time for us to create our own packages:

Creating your own packages is a difficult, complex process, involving many lines of code, long hours late at night with lots of coffee, and the ritual sacrifice of many goats. Just kidding. To create a package of classes, you have three basic steps to follow, which I'll explain in the following sections.

Ha, ha -- that's very funny, Lemay...

The first step is to decide what the name of your package is going to be. The name you choose for your package depends on how you are going to be using those classes. Perhaps your package will be named after you, or perhaps after the part of the Java system you're working on (like graphics or hardware_interfaces). If you're intending your package to be distributed to the Net at large, or as part of a commercial product, you'll want to use a package name (or set of package names) that uniquely identifies you or your organization or both.

Well, I'm not distributing packages to the Net -- at least, not yet.

Step two in creating packages is to create a directory structure on your disk that matches the package name. If your package has just one name (mypackage), you'll only have to create a directory for that one name. If the package name has several parts, however, you'll have to create directories within directories. For the package name edu.nonsense.eng.fooblitzky, you'll need to create an edu directory and then create a nonsense directory inside edu, an eng directory inside nonsense, and a fooblitzky directory inside eng. Your classes and source files can then go inside the fooblitzky directory.

I think I'll just do it the easy way for now, with just a single name.

The final step to putting your class inside packages is to add the package command to your source files. The package command says "this class goes inside this package," and is used like this:

package myclasses;
package edu.nonsense.eng.fooblitzky;
package java.awt;

OK, this makes sense -- except, of course, I'm not allowed to call my package java.awt as that's already built in.

Yesterday you learned all about the four Ps of protection and how they apply (primarily) to methods and variables and their relationship to other classes. When referring to classes and their relationship to other classes in other packages, you only have two Ps to worry about: package and public.

By default, classes have package protection, which means that the class is available to all the other classes in the same package but is not visible or available outside that package-not even to subpackages. It cannot be imported or referred to by name; classes with package protection are hidden inside the package in which they are contained.

I know that I sound like a broken record, but as usual, "yesterday" doesn't really mean yesterday. At last, we reach our first listing of the lesson:

Listing 16.1. The public class LinkedList.
 1: package  collections;
 2: 
 3: public class  LinkedList {
 4:     private Node  root;
 5: 
 6:     public  void  add(Object o) {
 7:         root = new Node(o, root);
 8:     }
 9:     . . .
10: }
11: 
12: class  Node {   // not public
13:     private Object  contents;
14:     private Node    next;
15: 
16:     Node(Object o, Node n) {
17:         contents = o;
18:         next     = n;
19:     }
20:     . . .
21: }

A linked list is a fairly common type of object -- we make them in C++ as well. This code isn't a complete program, so it's not something that I can compile and run. But I will comment on the line:

 7:         root = new Node(o, root);

This looks a little strange to me, but I suppose it's no different from x = x + 1; which means that the new value of x is one plus the old value of x. So the new value of root is a Node whose next is the old value of root. Thus next really means the old stuff, not the "next" stuff. I keep thinking that with linked lists in C++, next really means "next," and root is the "first" Node, not the last Node.

The author now moves on to interfaces:

Interfaces, like the abstract classes and methods you saw yesterday, provide templates of behavior that other classes are expected to implement. Interfaces, however, provide far more functionality to Java and to class and object design than do simple abstract classes and methods. The rest of this lesson explores interfaces: what they are, why they're crucial to getting the most out of the Java language for your own classes, and how to use and implement them.

So far, interfaces are a bit confusing to me.

When you first begin to design object-oriented programs, the concept of the class hierarchy can seem almost miraculous. Within that single tree you can express a hierarchy of different types of objects, many simple to moderately complex relationships between objects and processes in the world, and any number of points along the axis from abstract/general to concrete/specific. The strict hierarchy of classes appears, at first glance, to be simple, elegant, and easy to use.

Let's look at an even thornier example. Say you have a biological hierarchy with Animal at the top, and the classes Mammal and Bird underneath. Things that define a mammal include bearing live young and having fur. Behavior or features of birds include having a beak and laying eggs. So far, so good, right? So how do you go about creating a class for the platypus, which has fur, has a beak, and lays eggs? You'd need to combine behavior from two classes to form the Platypus class. And, because classes can have only one immediate superclass in Java, this sort of problem simply cannot be solved elegantly.

Other OOP languages include the concept of multiple inheritance, which solves this problem. With multiple inheritance, a class can inherit from more than one superclass and get behavior and attributes from all its superclasses at once.

And these "other OOP languages" definitely include C++. In fact, Jesse Liberty -- the "Lemay" of the C++ world -- has a Pegasus class that inherits from both Horse and Bird. So apparently, this doesn't work in Java.

So how do you solve the problem of needing common behavior that doesn't fit into the strict class hierarchy? Java, borrowing from Objective-C, has another hierarchy altogether separate from the main class hierarchy, a hierarchy of mixable behavior classes. Then, when you create a new class, that class has only one primary superclass, but it can pick and choose different common behaviors from the other hierarchy.

This other hierarchy is the interface hierarchy. A Java interface is a collection of abstract behavior that can be mixed into any class to add to that class behavior that is not supplied by its superclasses. Specifically, a Java interface contains nothing but abstract method definitions and constants-no instance variables and no method implementations.

I don't know what "Objective-C" is -- based on its name, I assume that it's a version of the C language that includes object-oriented programming, yet it isn't full C++.

Throughout this book you've gotten a taste of the difference between design and implementation in object-oriented programming, where the design of a thing is its abstract representation and its implementation is the concrete counterpart of the design. You saw this with methods, where a method's signature defines how it's used, but the method implementation can occur anywhere in the class hierarchy. You saw this with abstract classes, where the class's design provides a template for behavior, but that behavior isn't implemented until further down in the hierarchy.

And once again, I'm familiar with some of this from C++.

Classes and interfaces, despite their different definitions, have an awful lot in common. Interfaces, like classes, are declared in source files, one interface to a file. Like classes, they also are compiled using the Java compiler into .class files. And, in most cases, anywhere you can use a class (as a data type for a variable, as the result of a cast, and so on), you can also use an interface.

OK, I sort of understand this.

Now that you've grasped what interfaces are and why they're powerful (the "programming in the large" part), let's move on to actual bits of code ("programming in the small"). There are two things you can do with interfaces: use them in your own classes and define your own. Let's start with the former.

OK, I'm ready for Lemay's example now.

To use an interface, you include the implements keyword as part of your class definition. You did this back on Day 11, "More Animation, Images, and Sound," when you learned about threads and included the Runnable interface in your applet definition:

// java.applet.Applet is the superclass 
public class Neko extends java.applet.Applet
    implements Runnable {  // but it also has Runnable behavior
...
}

OK, I sort of remember this, even though "Day 11" was last year.

Let's examine one simple example-creating the new class Orange. Suppose you already have a good implementation of the class Fruit and an interface, Fruitlike, that represents what Fruits are expected to be able to do. You want an orange to be a fruit, but you also want it to be a spherical object that can be tossed, rotated, and so on.

Unlike the singly inherited class hierarchy, you can include as many interfaces as you need in your own classes, and your class will implement the combined behavior of all the included interfaces. To include multiple interfaces in a class, just separate their names with commas:

public class Neko extends java.applet.Applet 
    implements Runnable, Eatable, Sortable, Observable {
...
}

Remember that almost everywhere that you can use a class, you can use an interface instead. So, for example, you can declare a variable to be of an interface type:

Runnable aRunnableObject = new MyAnimationClass()

After using interfaces for a while, the next step is to define your own interfaces. Interfaces look a lot like classes; they are declared in much the same way and can be arranged into a hierarchy, but there are rules for declaring interfaces that must be followed.

To create a new interface, you declare it like this:

public interface Growable {
...
}

One trick to note about methods inside interfaces: Those methods are supposed to be abstract and apply to any kind of class, but how can you define parameters to those methods? You don't know what class will be using them!

So, for example, take the interface Fruitlike, which defines methods (with no arguments) for decay() and squish(). There might also be a method for germinateSeeds(), which has one argument: the fruit itself. Of what type is that argument going to be? It can't be simply Fruit, because there may be a class that's Fruitlike (that is, implements the Fruitlike interface) without actually being a fruit. The solution is to declare the argument as simply Fruitlike in the interface:

public interface Fruitlike {
    public abstract germinate(Fruitlike self) {
       ...
    }
}

This reminds me of something called "templates" in C++.

As with classes, interfaces can be organized into a hierarchy. When one interface inherits from another interface, that "subinterface" acquires all the method definitions and constants that its "superinterface" defined. To extend an interface, you use the extends keyword just as you do in a class definition:

public interface Fruitlike extends Foodlike { 
...
}

We finally reach the second listing of the lesson, which adds an interface to our linked lists from earlier:

Listing 16.2. Packages, classes, and interfaces.
 1: package  collections;
 2:
 3: public class  LinkedList {
 4:       private Node  root;
 5:
 6:       . . .
 7:       public Enumeration  enumerate() {
 8:           return new LinkedListEnumerator(root);
 9:     }
10: }
11: 
12: class  Node {
13:     private Object  contents;
14:     private Node    next;
15:
16:     . . .
17:     public  Object  contents() {
18:         return contents;
19:     }
20:
21:     public  Node    next() {
22:         return next;
23:     }
24: }
25: 
26: class  LinkedListEnumerator implements Enumeration {
27:     private Node  currentNode;
28: 
29:      LinkedListEnumerator(Node  root) {
30:         currentNode = root;
31:     }
32:  
33:     public boolean  hasMoreElements() {
34:         return currentNode != null;
35:     }
36:  
37:     public Object   nextElement() {
38:        Object  anObject = currentNode.contents();
39:  
40:         currentNode = currentNode.next();
41:        return  anObject;
42:    }
43: }

But once again, this isn't runnable code.

My Own Interface in Java

Unfortunately, I still don't have any runnable code to post here -- but I do have some examples of interfaces that I could implement someday. Consider the Quadrilateral Hierarchy from Geometry -- is a square a rhombus or a rectangle? In C++ we'd use multiple inheritance, but Lemay tells us that in Java, we must use an interface instead:

class Square extends Quadrilateral implements Rectanglelike, Rhombuslike {

In fact, Rhombuslike can itself extend other interfaces:

interface Rhombuslike extends Parallelogramlike, Kitelike {

In fact, notice that any quadrilateral that is both a parallelogram and a kite is a priori a rhombus. (Proof: pgrams have opposite sides congruent, kites have pairs of adjacent sides congruent, and so a figure that is both a pgram and a kite has all sides congruent, hence a rhombus. QED) So in fact there might not be anything to put in the body of Rhombuslike at all.

Rectanglelike might also extend Parallelogramlike, so there could be an error regarding whether Square derives Parallelogramlike from Rectanglelike or Rhombuslike.

Conclusion

2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30

Basketball season is over in California -- and to some Clippers fans, this sequence explains why. This is a list of all the dates in June when the team had to play a game.

When the Clippers closed out the Utah Jazz in Game 6 on June 18th, fans were hoping that there would be some more time off before the series against the Phoenix Suns. Instead, Game 1 of that series was played on June 20th. Many fans expected that the TV networks were to blame for the short rest -- and as it turns out, they're right.

The Western Conference Finals were played on even dates, while the Eastern Conference Finals are played on odd dates. If the NBA had waited until June 22nd to play Clippers vs. Suns Game 1, then Game 7 would have landed on the Fourth of July -- a major holiday. Unlike Christmas, the Fourth doesn't have a basketball tradition. Fans would have kept their TV's off and watched fireworks instead of the game. By starting Game 1 on June 20th, Game 7 would have been tonight instead of the Fourth.

Suppose the Clippers vs. Jazz series had gone the full seven games, forcing Game 1 of the conference finals to June 22nd. I suspect, in order to avoid the big holiday, Game 6 would have been tonight and Game 7 not until July 6th -- the next even date after the holiday. It's not that the TV networks are opposed to giving the players rest -- it's just that they would prefer the rest to occur on a holiday when very few people are watching TV. Unfortunately for the Clippers, that built-in holiday of rest was still two full weeks away at the start of the Suns series (though if John Adams had had his way, the holiday of rest would have been tonight with Game 7 on July 4th).

And so I hope you enjoy your Second of July, your Independence Day Adams today, as well as your Fourth of July holiday on Sunday.

No comments:

Post a Comment