Abstraction in Action


An abstraction is implemented by defining an abstract class using the abstract keyword in Java. This is shown in the following example, which defines the Student class as an abstract class. Remember that you cannot create an instance of any class designated as an abstract class. This means that you cannot declare an instance of the Student class. The Student class must be inherited by a subclass, which is shown later in this section.

 abstract class Student 
{

}

You can define data members and member methods of an abstract class. Member methods may or may not be designated an abstract method based on the needs of the class. A member method designated as an abstract method forces the programmer of the subclass to redefine the abstract member method.

Member methods not designated an abstract member method do not have to be defined in the subclass. The programmer who defines the subclass has the option of redefining the method or using the super class version of the method.

You define an abstract method in Java by using the keyword abstract followed by the data type of the return value and the signature of the method. This is illustrated in the next example, where we inserted the register() member method into the definition of the Student class.

In this example, the register() member method is granted public access using the public access specifier . It is an abstract method that doesn t return a value and doesn t have an argument list. The register() method also doesn t have a body defined for it because the register() method is an abstract method. The body of an abstract method is defined when the method is redefined by a subclass.

After the following Java example is the equivalent in C++, using a pure virtual function. A pure virtual function in C++ is indicated with the special =0 postfix, which identifies it as an abstract method, and the class it is in becomes an abstract class.

 //Java 
abstract class Student
{
public abstract void register();
}

//C++
class Student // C++ example
{
public:
virtual void register() =0 ;
}

The subclass definition must inherit the super class and define any methods that are designated abstract in the super class. This is shown in the following example, where the GradStudent class inherits the Student class by using the extends keyword.

Notice that the register() method is defined within the GradStudent class. The programmer who defined the GradStudent class doesn t have any alternative but to define the register() method. Failure to do so causes a compile error, which you ll see in the next section.

We purposely kept the register() method simple by having it display a one-line message on the screen when the method is invoked. You can easily use this example as a model for more complex methods in your own applications:

 class GradStudent extends Student{ 
public void register() {
System.out.print("Graduate Student Registered.");
}

The application can only declare an instance of the subclass, which is the GradStudent class in this example. Furthermore, only the register() method defined in the GradStudent class can be called from within the application, as shown in the next example. You cannot call the register() method defined in the Student class because that method is an abstract method and cannot be directly accessed from the application.

 class AbstractDemo { 
public static void main (String args[]) {
GradStudent myGradStudent = new GradStudent();
myGradStudent.register();
}
}

Here is the complete Java application that uses an abstract class and abstract member method. The first statement within the main() method uses the new operator to declare an instance of the GradStudent class. It also declares a reference to the GradStudent class, which is assigned the location of the instance.

The next statement calls the register() method of the GradStudent class, which displays a message on the screen saying that the graduate student has been registered.

 class AbstractDemo { 
public static void main (String args[]) {
GradStudent myGradStudent = new GradStudent();
myGradStudent.register();
}
}
abstract class Student
{
public abstract void register();
}
class GradStudent extends Student{
public void register() {
System.out.print("Graduate Student Registered.");
}
}

A similar example in C++ of a derived class that provides the required pure virtual (abstract) method, as dictated by its base class, would look like the following:

 class GradStudent : public Student{ 
public:
void register() {
cout << "Graduate Student Registered."<<endl;
}
}
}

Errors Galore

Expect compiler errors whenever abstraction is used in an application, but look upon those errors as a good thing. The purpose of abstraction is to force a programmer to define a method that is designated as an abstract method in a super class. Abstraction is also used to prevent an instance of a super class from being declared in an application.

The reason for imposing these limitations is because the abstract class has some but not necessarily all the detail needed to implement default methods. In previous examples, you saw that the Student class requires a registration procedure but doesn t have sufficient information to define details of that procedure. Programmers of subclasses that inherit the Student class provide those details.

Three common errors occur when abstraction is used:

  • The failure of the programmer to define an abstract method in a subclass

  • An attempt by the programmer to call the super class s abstract method

  • An attempt to declare an instance of the abstract super class in the program

Let s take a look at how failure to define an abstract method in a subclass can cause a compiler error. The next example is similar to other applications used in this chapter. It defines the Student class as an abstract class that contains the register() method, which is designated as an abstract method.

The programmer of the GradStudent class is expected to define details of the register() method, but the programmer decides not to do so because the register() method isn t called in the program (see Figure 6-4). You ll notice this in the main() method, where the program simply creates an instance of the GradStudent class.

click to expand
Figure 6-4: Failure to define the abstract member in a subclass causes a compiler error.

Try compiling this program and you ll discover that the compiler complains because the register() method is defined in the GradStudent class. You ll probably see an error message similar to this:

 class GradStudent must be declared abstract. It does not define void register() from class Student. 

You can fix this problem by defining a register() method in the GradStudent class definition and then recompiling the program, like so:

 class AbstractDemo { 
public static void main (String args[]) {
GradStudent myGradStudent = new GradStudent();
}
}
abstract class Student
{
public abstract void register();
}
class GradStudent extends Student{
}

Another common error occurs when the programmer of the subclass decides to call the abstract method rather than defining a corresponding method in the subclass. This is a common rookie mistake when abstract classes from a class library are used in an application because the programmer gets used to having all the methods defined for them in the super class and doesn t realize that an abstract method must be redefined in the subclass.

The follow example illustrates this problem. This application is nearly identical to the previous application except the programmer of the GradStudent class defines the register() method by simply calling the super class s register() method.

This is an acceptable practice, but not when the register() method is designated an abstract method. Try compiling this program and you ll receive the following error message. You can correct this problem by removing the call to the super.register() method in the GradStudent class s register() method.

 Can't directly invoke abstract method void register() in class Student. 
super.register();
^

class AbstractDemo {
public static void main (String args[]) {
GradStudent myGradStudent = new GradStudent();
myGradStudent.register();
}
}
abstract class Student
{
public abstract void register();
}
class GradStudent extends Student{
public void register() {
super.register();
}
}

The third common error that some programmers experience when using abstraction is to attempt to declare an instance of an abstract class. This is shown in the next example, where the programmer declares an instance of the Student class, called myStudent , in the second statement of the main() method.

You ve seen a similar statement used successfully in Chapter 4. This statement would also be successful here if it weren t for the fact that the Student class is an abstract class. You simply cannot declare an instance of an abstract class.

Try compiling this program, and you receive the following error message:

 class Student is an abstract class. It can't be instantiated. 
Student myStudent = new Student();

You can correct this error by removing the second statement in the main() method, thereby not attempting to declare an instance of the Student class, as shown here:

 class AbstractDemo { 
public static void main (String args[]) {
GradStudent myGradStudent = new GradStudent();
Student myStudent = new Student();
myGradStudent.register();
}
}
abstract class Student
{
public abstract void register();
}

class GradStudent extends Student{
public void register() {
System.out.print("Graduate Student Registered.");
}
}



OOP Demystified
OOP Demystified
ISBN: 0072253630
EAN: 2147483647
Year: 2006
Pages: 130

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net