In Dictionary of Object Technology: The Definitive Desk Reference, Donald G. Firesmith provides the following definition for the word polymorphism:
From https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html:
n. 1. the ability of a single name to refer to different things having different forms.
Firesmith defines overloading as:
n. any polymorphism whereby the same name is overloaded (i.e., is used for different, but analogous, abstractions).And he defines global overloading as:
n. any overloading in which the same name is used for abstractions in different contexts or scopes unrelated by inheritance.
From https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html:
You can use a construct called varargs to pass an arbitrary number of values to a method. You use varargs when you don't know how many of a particular type of argument will be passed to the method. It's a shortcut to creating an array manually.To use varargs, you follow the type of the last parameter by an ellipsis (three dots, ...), then a space, and the parameter name. The method can then be called with any number of that parameter, including none.
/* A social system in which the father is head of the household, having authority over women and children,
* and in which lineage is traced through the male line.
*
* — https://en.wiktionary.org/wiki/patriarchy
*/
public class Patriarchy
{
private static void printLineages(String heading, Descendant... lineage)
{
System.out.println(heading);
for (Descendant d : lineage)
System.out.println("\n" + d.toString());
}
private static Descendant[] getLineages(String[] names)
{
final int n = names.length;
final String a = n > 0 ? names[0] : Descendant.UNDEFINED;
final String b = n > 1 ? names[1] : Descendant.UNDEFINED;
final String c = n > 2 ? names[2] : Descendant.UNDEFINED;
Descendant[] bc = { new Son(b, a), new Grandson(c, b, a) };
return bc;
}
public static void main(String args[])
{
printLineages("EXAMPLE 1", new JohnSpurgeon());
System.out.println();
final String a = "Adam", b = "Cain", c = "Enoch";
printLineages("EXAMPLE 2", new Father(a), new Son(b, a), new Grandson(c, b, a));
System.out.println();
printLineages("EXAMPLE 3", getLineages(args));
}
}
/* NOTES
*
* 1. In addition to declaring methods, interfaces may also define static constants.
* Such constants are always static and final; in other words, they are static and
* final even if those keywords don't appear before the name of the constant.
* 2. Methods declared in an interface are public and abstract by default; i.e.,
* the keywords public and abstract may be used explicitly or they may be omitted.
* 3. The name of an interface may be used to specify the type of a variable. This
* technique is commonly used when the variable is a parameter. This is an example
* of global overloading.
*/
interface Descendant
{
// public static final String UNDEFINED = "undefined";
String UNDEFINED = "undefined";
// public abstract String whoAmI();
String whoAmI();
String whoIsMyFather();
String whoIsMyGrandfather();
}
class JohnSpurgeon implements Descendant
{
final public String whoAmI() { return "I am John Spurgeon."; }
final public String whoIsMyFather() { return "My father is Paul Spurgeon."; }
final public String whoIsMyGrandfather() { return "My father's father was Frank Spurgeon."; }
}
class Father implements Descendant
{
private final String firstInLine;
protected String self() { return this.firstInLine; }
protected String father() { return Descendant.UNDEFINED; }
protected String grandfather() { return Descendant.UNDEFINED; }
public Father(String me) { this.firstInLine = me; }
final public String whoAmI()
{
return "I am " + this.self() + ".";
}
public String whoIsMyFather()
{
return "My father, who art in heaven, hallowed be Thy name.";
}
final public String whoIsMyGrandfather()
{
return "My grandfather is " + this.grandfather() + ".";
}
public String toString()
{
return whoAmI() + "\n" + whoIsMyFather();
}
}
class Son extends Father
{
private final String secondInLine;
protected String self() { return secondInLine; }
protected String father() { return super.self(); }
public Son(String me, String myFather)
{
super(myFather);
secondInLine = me;
}
final public String whoIsMyFather()
{
return "My father is " + father() + ".";
}
public String toString()
{
return whoAmI() + "\n" + whoIsMyFather() + "\n" + whoIsMyGrandfather();
}
}
class Grandson extends Son
{
private final String thirdInLine;
protected final String self() { return thirdInLine; }
protected final String father() { return super.self(); }
protected final String grandfather() { return super.father(); }
public Grandson(String me, String myFather, String myGrandfather)
{
super(myFather, myGrandfather);
thirdInLine = me;
}
}
/* Command-line args: "a" "b" "c" EXAMPLE 1 JohnSpurgeon@5f205aa EXAMPLE 2 I am Adam. My father, who art in heaven, hallowed be Thy name. I am Cain. My father is Adam. My grandfather is undefined. I am Enoch. My father is Cain. My grandfather is Adam. EXAMPLE 3 I am b. My father is a. My grandfather is undefined. I am c. My father is b. My grandfather is a. */