15.15 RESTRICTIONS ON OVERIDING METHODS IN JAVA


15.15 RESTRICTIONS ON OVERIDING METHODS IN JAVA

The definition of an overriding method in a derived class must not violate the following restrictions:[13]

  1. The return type of an overriding method in a derived class must be the same as the return type of the overridden method in the base class. Consider the following example:

     class X {                                     // BASE     public float foo(double m) { return m; } } class Y extends public X {                     // DERIVED     public double foo(double n) { return n; }            // Error } 

    The compiler would not accept this. By using in the derived class a method of the same signature as a method in the base class, you have told the compiler that you want to provide an overriding method in the derived class for the method foo in the base class. The compiler would now insist that the return types for both versions of foo() be identical. Of course, if we were to change the parameter type of the derived-class foo to, say, float, the compiler would not complain. The derived-class foo would now be considered to be a different function, not meant for overriding the base-class foo. In contrast with C++, this restriction on the return type of an overriding method applies regardless of whether the return type is a primitive or a class-type object. Recall that for C++, for class type returns, the overriding function is allowed to have a return type that is a subtype of the value returned by the overridden function.

  2. The access restriction for an overriding method can be no tighter than the restriction on the base-class overridden method. So if the access restriction on the base-class method is, say, protected, the overriding method in the derived class can either be protected or public, but not private. Unlike with C++, a method declared in the private section of a class cannot be overridden. To illustrate this difference between C++ and Java, the following program is the Java version of the C++ program Private Virtual. cc shown earlier in Section 15.9. As with the C++ program, the classes Base and Derived each define a private method foo() in lines (A) and (C), respectively. Contrary to what happened in the C++ program,the Derived's foo() does not override Base's foo() here. This is made evident by our constructing a Derived object and assigning it to a variable p of type Base in line (G). Invoking Base's bar() on p in line (H) only invokes Base's foo() In other words, the foo() of Base does not behave polymorphically.

     
    // OverrideAccessRestrict.Java class Base { private int m; private void foo() { //(A) System.out.println("Base's foo invoked"); } public Base(int mm) { m = mm; } public void bar() { foo(); } //(B) } class Derived extends Base { private int n; private void foo() { //(C) System.out.println("Derived's foo invoked"); } public Derived(int mm, int nn) { //(D) super(mm); n = nn; } } class Test { public static void main(String[] args) { Base p = new Derived(10, 20); //(G) p.bar(); //output: Base's foo invoked //(H) } }

  3. The exception specification for an overriding function in a derived class must be a subset of the exception specification on the overridden base-class method. For illustration, the following example code will elicit a compiler error. The compiler will take notice of the fact that foo() in the derived classYhas the same signature as foo() in the base class X. Therefore, the compiler will assume that the derived class foo () is meant to override the base class foo (). But the compiler will refuse to accept the provided override definition because the exception specification for Y's foo() in line (B) below is not a subset of the exception specification for X's foo() in line (A).

     
    class Exception_1 extends Exception {} class Exception_2 extends Exception {} class X { // BASE private int m; public X(int mm) { m = mm; } public void foo() throws Exception_1 { //(A) System.out.println( "X's foo invoked"); throw new Exception_1(); } } class Y extends X { // DERIVED private int n; public Y(int mm, int nn) { super(mm); n = nn; } public void foo() throws Exception_2 { //(B) System.out.println( "Y's foo invoked"); throw new Exception_2(); } }

    The reader will recall that C++ places a similar restriction on the exception specifications for overriding functions.

    In the above example, it would be perfectly okay to have the overriding foo () ofYto throw no exceptions at all, since a null set is a subset of every set. So, in the following code fragment, Y's foo () is a legal overriding method for X's foo().

     
    class Exception_1 extends Exception {} class Exception_2 extends Exception {} class X { private int m; public X(int mm) { m = mm; } public void foo() throws Exception_1 { System.out.println( "X's foo invoked") throw new Exception_1(); } } class Y extends X { private int n; public Y(int mm, int nn) { super(mm); n = nn;} public void foo() { System.out.println("Y's foo invoked"); } }

[13]The reader is urged to carry out a point-by-point comparison of the restrictions listed here with those forCplus;++in Section 15.9.




Programming With Objects[c] A Comparative Presentation of Object-Oriented Programming With C++ and Java
Programming with Objects: A Comparative Presentation of Object Oriented Programming with C++ and Java
ISBN: 0471268526
EAN: 2147483647
Year: 2005
Pages: 273
Authors: Avinash Kak

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