Section 9.5. final

   

9.5 final

Inheritance and method overriding are very powerful, as we have seen. However, there are many occasions during which you do not want to allow classes to be extended and methods to be overridden. You disallow such things with the final keyword.

There could be a number of reasons for wanting to disallow class extension or method overriding.

9.5.1 final Disallows Inheritance

In order to prevent a class from being inherited, use the final keyword in its definition:

 public final class Class 

When you declare a class as final , all of its methods become implicitly final as well.

Note

As you may infer , you cannot declare a class both abstract and final . These concepts are at opposite ends of the spectrum: abstract says, "I have no implementation whatsoever. I only exist as a concept. You will have to do everything for me in a subclass." final , on the other hand, says, "There will never be any other versions of me. I am implemented completely. I'm the last one, and I'm as good as it gets."


The java.lang.Class class, which we discuss below, is final . The Class class has no public constructor, because Class objects get automatically constructed by the Java Virtual Machine when classes are loaded. Using final means that this is illegal:

 public final class MyClass {   //... } class SubClass extends MyClass { // Error! Cannot extend final   //... } 

This can protect the integrity of your work and help keep your application secure and working as you expect. Here is another example:

9.5.2 finalTest.java

 package javaforcf.chp9;  public final class finalTest {   public static void main(String[] args) {   finalTest obj  = new finalTest();   System.out.println(obj.getClass().getModifiers());   } } 

Running this program simply returns the int 17, the modifier for a public final class .

9.5.3 final Disallows Overriding

In keeping with behavior typical of final , declaring a method final disallows its being overridden. This works just as you would imagine. Let's look at a quick example:

9.5.4 FinalMethod.java

 package javaforcf.chp9;    // class is not final.   // we're going to extend it public class FinalMethod {   // the multiply method is final   // mutliplies two ints   final int multiply(int i, int j) {     return i * j;   }   public static void main(String[] args) {     FinalMethod obj  = new FinalMethod();       // okay. returns 15     System.out.println(obj.multiply(3,5));   } } 

The above class, FinalMethod , is not itself final . It contains a single final method.

9.5.5 FinalMethodExtender.java

 package javaforcf.chp9;  public class FinalMethodExtender extends FinalMethod {   public static void main(String[] args) {       // instantiate     FinalMethodExtender fme = new FinalMethodExtender();       /* call the method defined in the superclass          we don't define this here, the method is inherited          because of the extends keyword in the class dedinition          */     System.out.println(fme.multiply(7,8));       // prints 56   } } 

The above class runs fine and prints 56 . We can inherit and use the multiply() method normally, even though it is final .

We will now see what happens when we try to override this method in FinalMethodExtender . What if we just wrote the following?

 public double multiply(double d, double e) {   return d * e; } 

That is not overriding the method. It has a different signature, and overriding requires that the signatures match. Defining a couple of doubles and running that program would work fine. Note that if you do not create the double fields, you will get a compiler error, but it won't be because of finality. It will complain that the method call is ambiguous ”it doesn't know whether you mean the multiply() method from the superclass or this class. Why would that be? Because, as you'll recall from the second chapter, the JVM can perform this natural widening conversion. In order to really test this, we need to create a real override:

 public int multiply(int i, int j) {   System.out.println("Result: ");   return i * j; } 

Now, compiling and running the class will get this result:

 final method multiply(int, int) in class  javaforcf.chp9.FinalMethod cannot be overridden by method multiply(int, int) in class javaforcf.chp9.FinalMethodExtender. 

   
Top


Java for ColdFusion Developers
Java for ColdFusion Developers
ISBN: 0130461806
EAN: 2147483647
Year: 2005
Pages: 206
Authors: Eben Hewitt

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