Chapter 11. Creating More Powerful JavaBeans

Welcome to Day 11! Today, you'll learn more about some of the Java techniques you've already seen in passing—basing a class on another class, using inheritance, overriding Java methods, and more. These are all Java techniques that are essential to know if you're going to do anything beyond the most basic operations in JSP.

Creating More Powerful JavaBeans
  • Supporting inheritance

  • Creating subclasses and superclasses

  • Creating interfaces

  • Overloading methods

  • Overriding methods

  • Creating abstract classes

  • Runtime polymorphism

  • Using <jsp:plugin>

Learning these techniques will enable you to build more powerful Java code and more powerful JavaBeans.

Why Inheritance?

Java is a true object-oriented language, and it uses inheritance a great deal. As you know, the developers at Sun Microsystems have created huge packages—in fact, entire class libraries—full of classes that you can use by basing your own classes on them. This is important if, for example, you want to create a custom tag, because you base such tags on prebuilt classes like TagSupport that the developers at Sun have written for you already.

Why Inheritance?

In other words, inheritance is all about code reuse. When you've created a powerful Java class (like TagSupport), and you want to base all kinds of subclasses on that class, using inheritance is great.

Using Inheritance

Here's an example showing how to create a subclass using inheritance. Say you have a class named vehicle that has one method, start, which you can use to start the vehicle, and which prints out "Starting...<BR>":

class vehicle 
{
    public void start()
    {
        out.println("Starting...<BR>");
    }
}

There are all kinds of vehicles, so if you want to specialize the vehicle class into an automobile class, you can use inheritance with the extends keyword. Here's how you declare automobile as a subclass of vehicle:

class automobile extends vehicle 
{
    .
    .
    .
}

This code indicates that automobile is derived from the vehicle class, which means that automobile will inherit the start method from vehicle. You can also add your own data members and methods in subclasses, as in this case, where the code adds a method named drive to the automobile class:

class automobile extends vehicle 
{
    public void drive()
    {
        out.println("Driving...<BR>");
    }
}

Now I can access both the start method and the drive method in objects of the automobile class, as you see in Listing 11.1.

Example 11.1. Using Inheritance (ch11_01.jsp)

<HTML>
    <HEAD>
        <TITLE>Using Inheritance</TITLE>
    </HEAD>

    <BODY>
        <H1>Using Inheritance</H1>
        <%!
            javax.servlet.jsp.JspWriter localOut;

            class vehicle
            {
                public void start()  throws java.io.IOException
                {
                    localOut.println("Starting...<BR>");
                }
            }

            class automobile extends vehicle
            {
                public void drive() throws java.io.IOException
                {
                    localOut.println("Driving...<BR>");
                }
            }
        %>
        <%
            localOut = out;

            out.println("Creating an automobile...<BR>");
            automobile a = new automobile();
            a.start();
            a.drive();
        %>
    </BODY>
</HTML>

You can see the results in Figure 11.1, where, as you see, both the start and drive methods are available to the automobile object.

Inheritance in action.

Figure 11.1. Inheritance in action.

This example put all Java code in one JSP page; if you're creating a JavaBean, note that you can also define multiple classes like vehicle and automobile in the same Java file that they're used in:

class vehicle 
{
    public void start() throws java.io.IOException
    {
        System.out.println("Starting...<BR>");
    }
}

class automobile extends vehicle
{
    public void drive() throws java.io.IOException
    {
        System.out.println("Driving...<BR>");
    }
}

public class application
{
    automobile a = new automobile();

    a.drive();
        .
        .
        .

Tip

If you do define multiple classes in the same .java file, one class—and only one class (the class with the same name as the file itself)—must be declared with the public keyword. This was discussed in Day 6, “Creating JSP Components: JavaBeans”—see that day for examples.

You can also separate the Java code among multiple .java files. For example, for the vehicle class, you use a file named vehicle.java:

public class vehicle 
{
    public void start() throws java.io.IOException
    {
        System.out.println("Starting...<BR>");
    }
}

Then you compile vehicle.java into vehicle.class with javac. You can now access the vehicle class by importing it into another .java file using the Java import statement:

import vehicle; 

class automobile extends vehicle
{
    public void drive() throws java.io.IOException
    {
        System.out.println("Driving...<BR>");
    }
}

public class application
{
    automobile a = new automobile();

    a.drive();
        .
        .
        .

Tip

If you've stored vehicle.class in another directory, such as C:classes, don't forget to set the CLASSPATH variable so Java can find vehicle.class, like this in Windows: SET CLASSPATH=c:classes.

Using Access Specifiers

Using Access Specifiers
access class classname [extends ...] [implements ...] 
{
    [access] [static] type variable1;
        .
        .
        .
    [access] [static] type variableN;

    [access] [static] type method1 (parameter_list)
    {
        .
        .
        .
    }
    .
    .
    .
    [access] [static] type methodN (parameter_list)
    {
        .
        .
        .
    }
}
Using Access Specifiers

Table 11.1. Scope by Access Specifier

Location

Private

No Specifier

Protected

Public

Same class

x

x

x

x

Subclass in the same package

 

x

x

x

Non-subclass in the same package

 

x

x

x

Subclass in another package

  

x

x

Non-subclass in another package

   

x

For example, if you made the start method private to the vehicle class, you couldn't call it in code like this:

class vehicle 
{
    private void start()  throws java.io.IOException
    {
        localOut.println("Starting...<BR>");
    }
}
    .
    .
    .
    out.println("Creating an automobile...<BR>");

    automobile a = new automobile();
    a.start();         // This won't work!
    a.drive();

Because declaring a member using private restricts that member to its class, JSP will say it can't find the start method if you try to load this page. On the other hand, declaring a member protected restricts its scope to code in the same class and subclass of the class it's declared in, so the version you see in Listing 11.2 will work.

Example 11.2. Using Protected Access (ch11_02.jsp)

<HTML>
    <HEAD>
        <TITLE>Using Restricted Access</TITLE>
    </HEAD>

    <BODY>
        <H1>Using Restricted Access</H1>
        <%!
            javax.servlet.jsp.JspWriter localOut;

            class vehicle
            {
                protected void start()  throws java.io.IOException
                {
                    localOut.println("Starting...<BR>");
                }
            }

            class automobile extends vehicle
            {
                public void drive() throws java.io.IOException
                {
                    localOut.println("Driving...<BR>");
                }
            }
        %>
        <%
            localOut = out;

            out.println("Creating an automobile...<BR>");
            automobile a = new automobile();
            a.start();
            a.drive();
        %>
    </BODY>
</HTML>

You can see the results in Figure 11.2. The protected keyword used here is one you use specifically with inheritance, because it permits access in the current class and the subclasses of the current class, but not otherwise, so it's great for the utility routines your code needs.

Using restricted access.

Figure 11.2. Using restricted access.

Here's another question—what if a base class has a constructor? How do you reach that constructor from a derived class? That's coming up next.

Calling Superclass Constructors

As you know, when you create an object, Java uses a constructor, and you can pass data to the constructor to customize that object. A constructor is a method that has the same name as its class and needs no return value specifier like int or void. Say that you have a class named a, for example; you can give it a constructor with no parameters this way:

class a 
{
    a()
    {
        out.println("In a's constructor...<BR>");
    }
}

Then you derive a subclass, b, from a:

class b extends a 
{
}

Now when you create an object of class b, the constructor in class a is called automatically:

b newObject = new b(); 

You could modify this constructor to accept data you pass to it, and store that data in the object (see the section “Creating a Constructor” in Day 6). That's all fine, but now suppose that you also added a constructor that takes no parameters to class b, the derived class, as you see in Listing 11.3.

Example 11.3. Calling Superclass Constructors (ch11_03.jsp)

<HTML>
    <HEAD>
        <TITLE>Calling Superclass Constructors</TITLE>
    </HEAD>

    <BODY>
        <H1>Calling Superclass Constructors</H1>
        <%!
            javax.servlet.jsp.JspWriter localOut;

            class a
            {
                a() throws java.io.IOException
                {
                    localOut.println("In a's constructor...<BR>");
                }
            }

            class b extends a
            {
                b() throws java.io.IOException
                {
                    localOut.println("In b's constructor...<BR>");
                }
            }
        %>
        <%
        localOut = out;

        b obj = new b();
        %>
    </BODY>
</HTML>

Now what happens? You can see the results in Figure 11.3—in this case, when you create an object of class b, both constructors from a and b are called.

Handling superclass constructors in code.

Figure 11.3. Handling superclass constructors in code.

There's more to consider here—suppose, for example, you change b's constructor so it takes one parameter, as you see in Listing 11.4.

Example 11.4. Using Parameterized Constructors (ch11_04.jsp)

<HTML>
    <HEAD>
        <TITLE>Using Parameterized Constructors</TITLE>
    </HEAD>

    <BODY>
        <H1>Using Parameterized Constructors</H1>

        <%!
            javax.servlet.jsp.JspWriter localOut;

            class a
            {
                a() throws java.io.IOException
                {
                    localOut.println("In a's constructor...<BR>");
                }
            }

            class b extends a
            {
                b(String s) throws java.io.IOException
                {
                    localOut.println("In b's String constructor...<BR>");
                    localOut.println(s);
                }
            }
        %>
        <%
            localOut = out;

            b obj = new b("Hello from JSP!<BR>");
        %>
    </BODY>
</HTML>

Now what happens? Here, the constructors of both classes a and b are called, as you see in Figure 11.4—the b class constructor that takes a string is called, and the a class constructor that takes no parameters is also called.

Calling a superclass's constructor from a parameterized constructor.

Figure 11.4. Calling a superclass's constructor from a parameterized constructor.

Calling a superclass's constructor from a parameterized constructor.
class a 
{
    a()
    {
        out.println("In a's constructor...<BR>");
    }

    a(String s)
    {
        out.println("In a's String constructor...<BR>");
        out.println(s);
    }
}

Now say that you want to call the constructor in class a with the String parameter instead of the default constructor—how do you do that? You do that by calling the super method in class b's constructor, as you see in Listing 11.5.

Example 11.5. Working with Constructors and Inheritance (ch11_05.jsp)

<HTML>
    <HEAD>
        <TITLE>Working With Constructors and Inheritance</TITLE>
    </HEAD>

    <BODY>
        <H1>Working With Constructors and Inheritance</H1>
        <%!
            javax.servlet.jsp.JspWriter localOut;

            class a
            {
                a() throws java.io.IOException
                {
                    localOut.println("In a's constructor...<BR>");
                }
                a(String s)  throws java.io.IOException
                {
                    localOut.println("In a's String constructor...<BR>");
                    localOut.println(s);
                }
            }

            class b extends a
            {
                b(String s) throws java.io.IOException
                {
                    super(s);
                    localOut.println("In b's String constructor...<BR>");
                    localOut.println(s);
                }
            }
        %>
        <%
            localOut = out;

            b obj = new b("Hello from JSP!<BR>");
        %>
    </BODY>
</HTML>

When you create an object of class b in this case, the constructor that takes a String parameter in class a is called, not the default constructor, as you see in Figure 11.5.

Working with constructors and inheritance.

Figure 11.5. Working with constructors and inheritance.

Here's the question—why is the constructor that takes a String parameter called, and not class a's default constructor? The reason is that you've used the super method to call a particular superclass constructor—the one that takes a String parameter:

b(String s) throws java.io.IOException 
{
    super(s);
    localOut.println("In b's String constructor...<BR>");
    localOut.println(s);
}

Note

Note that if you use super to call a superclass's constructor, the line in which you do so must be the first line of code in a constructor (if it's any other line, Java will have problems with your code).

Overloading Methods

Overloading Methods
  • print(boolean b)—. Print a Boolean value.

  • print(char c)—. Print a character.

  • print(char[] s)—. Print an array of characters.

  • print(double d)—. Print a double-precision floating-point number.

  • print(float f)—. Print a floating-point number.

  • print(int i)—. Print an integer.

  • print(long l)—. Print a long integer.

Each of these versions of print has a different argument type, and Java knows which version to use depending on the type of argument you pass to print. You can also specify different numbers of parameters (not just different types) for a method in order to overload it.

How do you overload a method? You simply define the method multiple times, each with its own unique argument list. For example, you can see how Listing 11.6 overloads the printText method to take no arguments and one String argument.

Example 11.6. Overloading Methods (ch11_06.jsp)

<HTML>
    <HEAD>
        <TITLE>Overloading Methods</TITLE>
    </HEAD>

    <BODY>
        <H1>Overloading Methods</H1>

        <%!
            javax.servlet.jsp.JspWriter localOut;

            void printText() throws java.io.IOException
            {
                localOut.println("Hello!<BR>");
            }

            void printText(String s) throws java.io.IOException
            {
                localOut.println(s + "<BR>");
            }
        %>
        <%
        localOut = out;

        printText();
        printText("Hello from JSP!");
        %>
    </BODY>
</HTML>

Overriding Methods

Overriding Methods

Here's an example. In this case, the code starts with a base class named animal that has one method, breathe. When you call breathe, it prints out Breathing...<BR>:

class animal 
{
    public void breathe()
    {
        out.println("Breathing...<BR>");
    }
}

Now say that you want to derive a new class from animal named trout. As things stand, the breathe method in the trout class prints out Breathing...<BR>. Because trout don't breathe in the same way as land animals—they use gills—you decide it would be better if it printed out something like Gilling...<BR> instead. To do that, you can override the breathe method in the trout class simply by defining a new version with the same parameter list:

class animal 
{
    public void breathe()
    {
        out.println("Breathing...<BR>");
    }
}

class trout extends animal
{
    public void breathe()
    {
        out.println("Gilling...<BR>");
    }
}

Now you've overridden the version of breathe you've inherited from the animal class. You can create new objects of the animal and trout classes and call their breathe methods, as you see in Listing 11.7.

Example 11.7. Overriding Methods (ch11_07.jsp)

<HTML>
    <HEAD>
        <TITLE>Overriding Methods</TITLE>
    </HEAD>

    <BODY>
        <H1>Overriding Methods</H1>

        <%!
            javax.servlet.jsp.JspWriter localOut;

            class animal
            {
                public void breathe()  throws java.io.IOException
                {
                    localOut.println("Breathing...<BR>");
                }
            }

            class trout extends animal
            {
                public void breathe()  throws java.io.IOException
                {
                    localOut.println("Gilling...<BR>");
                }
            }
        %>
        <%
            localOut = out;

            out.println("Creating an animal object...<BR>");
            animal a = new animal();
            a.breathe();

            out.println();
            out.println("Creating a trout object...<BR>");
            trout t = new trout();
            t.breathe();
        %>
    </BODY>
</HTML>

You can see the results in Figure 11.6, showing that the breathe method is indeed overridden in the trout class.

Overriding a method.

Figure 11.6. Overriding a method.

Using Superclass Variables with Subclassed Objects

One powerful aspect of OOP in Java is that you can assign a subclass object to a variable of a superclass type. For example, say that class a is the superclass of b and that you have a variable of class a; it turns out that you can assign object references of class b to that variable, as well as object references of class a.

That's made easier to understand in an example. This example uses the vehicle class discussed earlier, deriving a new class called aircraft from vehicle—and then a new class called plane from aircraft:

class vehicle 
{
    public void start()
    {
        out.println("Starting...<BR>");
    }
}

class aircraft extends vehicle
{
    public void fly()
    {
        out.println("Flying...<BR>");
    }
}

class plane extends aircraft
{
    public void fly()
    {
        out.println("Flying...<BR>");
    }
}

To create a new object of the plane class, you can use this code:

out.println("Creating a plane...<BR>"); 
plane p = new plane();
p.start();

This code assigns the new plane object to a variable of the plane type—but you can also assign the new plane object to a variable of base class vehicle, as you see in Listing 11.8.

Example 11.8. Using Superclass Variables with Subclassed Objects (ch11_08.jsp)

<HTML>
    <HEAD>
        <TITLE>Using Superclass Variables With Subclassed Objects</TITLE>
    </HEAD>

    <BODY>
        <H1>Using Superclass Variables With Subclassed Objects</H1>

        <%!
            javax.servlet.jsp.JspWriter localOut;

            class vehicle
            {
                public void start() throws java.io.IOException
                {
                    localOut.println("Starting...<BR>");
                }
            }

            class aircraft extends vehicle
            {
                public void fly() throws java.io.IOException
                {
                    localOut.println("Flying...<BR>");
                }
            }

            class plane extends aircraft
            {
                public void fly() throws java.io.IOException
                {
                    localOut.println("Flying...<BR>");
                }
            }
        %>
        <%
            localOut = out;

            out.println("Creating a plane object...<BR>");
            vehicle p = new plane();
            p.start();
            //p.fly();
        %>
    </BODY>
</HTML>

You can see the results in Figure 11.7—as you see, this code worked without problem, even though it assigned an object of the subclass plane to a variable of the superclass vehicle.

Assigning subclassed objects to superclass variables.

Figure 11.7. Assigning subclassed objects to superclass variables.

Note that Listing 11.8 expressly comments out the line p.fly(). The reason is that the fly method is defined in the aircraft and plane classes, which are subclasses of vehicle. This means you can't call those methods using a variable of class vehicle. That is to say, an object variable a will only give you access to those items which are members of its own class—you won't be able to access any members that are not members of a's class, even if you store an object of subclass b in it and b supports additional members.

The fact that you can assign subclass objects to superclass variables has an interesting use in Java, and that's coming up next.

Using Runtime Polymorphism

Using Runtime Polymorphism

Here's an example. In this example, the code creates a class named a, a subclass of a named b, a subclass of b named c, and a subclass of c named d, each of which has a print method:

class a 
{
    public void print()
    {
        out.println("Hello from a...<BR>");
    }
}

class b extends a
{
    public void print()
    {
        out.println("Hello from b...<BR>");
    }
}

class c extends a
{
    public void print()
    {
        out.println("Hello from c...<BR>");
    }
}

class d extends a
{
    public void print()
    {
        out.println("Hello from d...<BR>");
    }
}

Now you can create an object of each class:

a a1 = new a(); 
b b1 = new b();
c c1 = new c();
d d1 = new d();
    .
    .
    .

To show how runtime polymorphism works, this example also creates a variable named baseClassVariable of class a:

a a1 = new a(); 
b b1 = new b();
c c1 = new c();
d d1 = new d();
a baseClassVariable;
    .
    .
    .

Now you can place the objects of all different classes in baseClassVariable, and when you call the print method, the print method of the corresponding class will be called, as you see in Listing 11.9.

Example 11.9. Passing the out Object to a Method (ch11_09.jsp)

<HTML>
    <HEAD>
        <TITLE>Runtime Polymorphism</TITLE>
    </HEAD>

    <BODY>
        <H1>Runtime Polymorphism</H1>

        <%!
            javax.servlet.jsp.JspWriter localOut;

            class a
            {
                public void print() throws java.io.IOException
                {
                    localOut.println("Hello from a...<BR>");
                }
            }

            class b extends a
            {
                public void print() throws java.io.IOException
                {
                    localOut.println("Hello from b...<BR>");
                }
            }

            class c extends a
            {
                public void print() throws java.io.IOException
                {
                    localOut.println("Hello from c...<BR>");
                }
            }

            class d extends a
            {
                public void print() throws java.io.IOException
                {
                    localOut.println("Hello from d...<BR>");
                }
            }
        %>
        <%
            localOut = out;

            a a1 = new a();
            b b1 = new b();
            c c1 = new c();
            d d1 = new d();
            a baseClassVariable;

            baseClassVariable = a1;
            baseClassVariable.print();

            baseClassVariable = b1;
            baseClassVariable.print();

            baseClassVariable = c1;
            baseClassVariable.print();

            baseClassVariable = d1;
            baseClassVariable.print();
        %>
    </BODY>
</HTML>

You can see the results in Figure 11.8, where, as you see, the variable named baseClassVariable was able to contain objects of classes a, b, c, and d.

Working with runtime polymorphism.

Figure 11.8. Working with runtime polymorphism.

Using runtime polymorphism, you can write code that will handle many different types of objects, and you don't have to decide on the actual object type (you might pass the object to a method whose code uses runtime polymorphism, for example) until runtime.

Note

Don't forget that if you use runtime polymorphism, an object variable a will only give you access to those items that are members of its own class. If you store a subclass object in a, you won't be able to access any of its members that are not also members of the a class.

Creating Abstract Classes

When you develop your own classes for distribution to other programmers, you might want to insist that they customize your code in a way that you can't—for example, you might want them to customize the getMyName method to return their name.

Creating Abstract Classes

Here's an example that creates a class named a that has a method named printem, which prints out text. The printem method gets the text to print by calling a method named getText:

class a 
{
    String getText();

    public void printem()
    {
        out.println(getText());
    }
}
Creating Abstract Classes

To make sure other programmers know that they must provide a definition of the getText method, you can make that method abstract, which means you must make the class itself abstract as well:

abstract class a 
{
    abstract String getText();

    public void printem()
    {
        out.println(getText());
    }
}

Now when you subclass a, you have to provide a definition of getText:

class b extends a 
{
    String getText()
    {
        return "Hello from JSP!";
    }
}

You can see how this all looks in code in Listing 11.10, where the abstract method and class are declared and used in the code.

Tip

You cannot create objects of an abstract class directly—you have to derive a class from the abstract class and use that derived class instead.

Example 11.10. Using Abstract Classes (ch11_10.jsp)

<HTML>
    <HEAD>
        <TITLE>Using Abstract Classes</TITLE>
    </HEAD>

    <BODY>
        <H1>Using Abstract Classes</H1>

        <%!
            javax.servlet.jsp.JspWriter localOut;

            abstract class a
            {
                abstract String getText() throws java.io.IOException;

                public void printem() throws java.io.IOException
                {
                    localOut.println(getText());
                }
            }

            class b extends a
            {
                String getText() throws java.io.IOException
                {
                    return "Hello from JSP!";
                }
            }
        %>
        <%
            localOut = out;

            b bObject = new b();

            bObject.printem();
        %>
    </BODY>
</HTML>

You can see the results in Figure 11.9.

Inheriting abstract classes.

Figure 11.9. Inheriting abstract classes.

Using Interfaces for Multiple Inheritance

Using Interfaces for Multiple Inheritance
class a extends b, c      // Will not work! 
{
    .
    .
    .
}

However, there are alternatives that go some way in supporting multiple inheritance. For example, you can use single inheritance in stages:

class a 
{
    .
    .
    .
}

class b extends a
{
    .
    .
    .
}

class c extends b
{
    .
    .
    .
}

In this way, class c inherits both classes a and b. This is not true multiple inheritance, because one class has to build on the other—they can't be completely independent classes.

Using Interfaces for Multiple Inheritance
interface a 
{
    .
    .
    .
}

interface b
{
    .
    .
    .
}

Now you can use these two interfaces with the implements keyword:

class c implements a, b 
{
    .
    .
    .
}

Interfaces declare, but do not define methods. It's up to you to implement the interface's methods, just as it was with abstract classes.

Here's an example that creates an interface named Printem with one method: printText. To create an interface, you use the interface statement and list the prototypes (that is, method declarations without bodies) of the methods you want in the interface:

interface Printem 
{
    void printText();
}

Now you can implement this interface in the class named a for example, as you see in Listing 11.11.

Example 11.11. Creating a Java Interface (ch11_11.jsp)

<HTML>
    <HEAD>
        <TITLE>Creating a Java Interface</TITLE>
    </HEAD>

    <BODY>
        <H1>Creating a Java Interface</H1>

        <%!
            javax.servlet.jsp.JspWriter localOut;

            interface Printem
            {
                void printText() throws java.io.IOException;
            }

            class a implements Printem
            {
                public void printText() throws java.io.IOException
                {
                    localOut.println("Hello from JSP!");
                }
            }
        %>
        <%
            localOut = out;

            a printer = new a();
            printer.printText();
        %>
    </BODY>
</HTML>

You can see the results in Figure 11.10. Now you've successfully implemented an interface.

Creating a Java interface.

Figure 11.10. Creating a Java interface.

Summary

Today we looked at some Java techniques that are integral to object-oriented programming. To start, you learned how to use a superclass to create a subclass with the extends keyword.

You can use access specifiers to specify how data members and methods will be inherited. There are three access specifiers—public, protected, and private.

Overloading a method means providing more than one definition of the method. Each such definition must have a unique argument list so that Java knows which one you want to use by the argument types and number of arguments you pass to the method.

Methods can also be overridden, which means you can redefine a method from a superclass in a subclass. In this case, the argument list must be the same in the overriding and overridden methods.

You can create abstract classes in Java, which can contain abstract methods. You can't create objects directly from abstract classes—you have to derive a class based on them. In the derived class, you must define any abstract members of the superclass.

Runtime polymorphism is based on the fact that you can store subclass objects in superclass variables, which means you don't have to set the exact class of an object in a particular variable until runtime. However, you cannot access any members in the subclass object that are not also part of the superclass.

You also learned that Java uses interfaces as a partial implementation of multiple inheritance, and how to create and implement an interface. Tomorrow, you'll put this knowledge to work when you start creating Java servlets.

Q&A

Q1:

Can I still access an overridden method?

A1:

Yes, you can, using the super keyword. If you've overridden a method named method1, you can still access the overridden version in the superclass as super.method1.

Q2:

Is there some way to stop a method from being overridden?

A2:

Yes, you can use the Java keyword final—see the Java documentation for more information on that.

Workshop

This workshop tests whether you understand all the concepts you learned today. It's a good idea to master today's concepts by honing your knowledge here before starting tomorrow's material. You can find the answers to the quiz questions in Appendix A.

Quiz

1:

If a superclass has a default constructor, how do you call that constructor if you create an object of a subclass of that superclass?

2:

How can you select which constructor of a superclass is called?

3:

What access specifier do you use to restrict a method to the current class and any classes based on that class?

4:

What's the difference between overloading and overriding a method?

5:

If superclass class1 supports methods a, b, and c, and subclass class2 supports methods a, d, and e, which methods can you use with an object of class2 you've stored in a variable of class1?

Exercises

1:

Abstract classes are a topic that can cause some confusion to inexperienced Java programmers, because you can't create an object of an abstract class directly (you must first base a class on the abstract class and then create an object of the subclass). To get some familiarity with abstract classes, create one now named SuperDuperCode that you can distribute to other programmers. Include an abstract method, getSupport, that returns a (fictitious) tech support phone number that anyone who uses SuperDuperCode must implement, and create an object that implements SuperDuperCode to check whether getSupport works as it should.

2:

Because interfaces are often used to permit a version of multiple inheritance, modify the code in Listing 11.11 so that class a implements not only the Printem interface, but also a new interface named Textem. The Textem interface should include a method named getText, which supplies the text, “Hello from JSP!”, which the Printem interface's printText method will display in a Web page.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.73.207