|
|
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 5 of 7
Listing 4. Cats1.java
// Cats1.java
class Cat
{
String getInfo ()
{
return "?";
}
}
class Lion extends Cat
{
String getInfo ()
{
return "king of the jungle";
}
}
class Cheetah extends Cat
{
String getInfo ()
{
return "great speed";
}
}
class Tiger extends Cat
{
String getInfo ()
{
return "has stripes";
}
}
class Cats1
{
public static void main (String [] args)
{
Cat [] cats =
{
new Lion (),
new Cheetah (),
new Tiger (),
new Cat ()
};
for (int i = 0; i < cats.length; i++)
System.out.println (cats [i].getInfo ());
}
}
Cats1 presents three hierarchies of cat-related classes. At the top of those hierarchies sits a Cat class. Even though that class is basically empty, its purpose is to extract commonality found among all cats. Cats1 confines that commonality to a single getInfo() method, and subclasses override getInfo() to return cat-specific information.
Cats1's main() method declares an array of Cat objects and assigns a new Cat object to each entry. It makes sense to create Lion, Cheetah, and Tiger objects, because those objects represent specific kinds of cats. But does it also make sense to create a Cat object and assign its reference to an array entry? Does Cat represent a specific kind of cat? I think not. My opinion stems from the following Cats1 output:
king of the jungle great speed has stripes ?
That final ? signifies the output from calling Cat's getInfo() method. The question mark indicates that the code cannot provide specific information about something so generic. Ideally,
you do not want such a situation to crop up in your class hierarchies.
Fortunately, Java provides a way to prevent object creation from generic classes. Prefixing a class signature with the abstract keyword results in an abstract class. Any attempt to create an object from an abstract class causes a compiler error. Listing
5's Cats2 source code demonstrates an abstract class declaration:
Listing 5. Cats2.java
// Cats2.java
abstract class Cat
{
abstract String getInfo ();
}
class Lion extends Cat
{
String getInfo ()
{
return "king of the jungle";
}
}
class Cheetah extends Cat
{
String getInfo ()
{
return "great speed";
}
}
class Tiger extends Cat
{
String getInfo ()
{
return "has stripes";
}
}
class Cats2
{
public static void main (String [] args)
{
Cat [] cats =
{
new Lion (),
new Cheetah (),
new Tiger (),
// new Cat ()
};
for (int i = 0; i < cats.length; i++)
System.out.println (cats [i].getInfo ());
}
}
Cats2 prefixes the Cat class signature with keyword abstract. To prove that you cannot create an object from Cat, uncomment the new Cat () line in the above cats array declaration and attempt to compile. You will receive a compiler error message.
Cats2 also demonstrates an abstract method: Cat's getInfo(). Prefixing a method signature with keyword abstract accomplishes the following tasks:
abstractYou introduce an abstract method into an abstract class when that method identifies a common behavior that manifests itself
(in subclasses) in different ways. For example, the get-information behavior found in Cats2 manifests itself somewhat differently in the Lion, Cheetah, and Tiger subclasses. Although each method currently returns a different string literal, you might change each method to contain additional
logic unique to its class. Also, an abstract method's presence in an abstract superclass allows you to assign a subclass object
reference to the superclass object reference variable and (through inclusion/subtype polymorphism) call the more specific
subclass method.
switch statements start reappearing in your code in "Java Tip 30Polymorphism and Java," Philip Bishop (JavaWorld): http://www.javaworld.com/javaworld/javatips/jw-javatip30.html