The
rules for overriding a method are as follows:
1) The argument list must exactly match that of the overridden method.
If they don't
match, you can end up with an overloaded method you didn't intend.
Example
:
class
Base{
public
void add(int x,int y){
}
}
class
Sub extends Base{
public
void add(float x,float y){
}
}
Where
Sub class overloads the add(int,int) method.If you want to override
the Base class add(int,int) method declare the method as given below.
class
Sub extends Base{
public
void add(int x,int y){
}
}
2) The return type must be the same as, or a subtype of, the return type
declared in
the original overridden method in the superclass(covariant returns.)
Example :
class
Base{
public
void
fun(){ //Line 2
}
}
class
Sub extends
Base{
public
int
fun(){
//Line 6
}
}
Here
you will get a compile time error that The
return type is incompatible with Base.fun()
at Line 6.It won't even act as an overloaded method because by simply changing return type can't overload one method.
For
overriding a function, if the return type of the base class function
is a primitive type (i.e.
void,byte,short,int,long,flat,double,boolean,char) then sub class
function should also be with the same return type.
If
the return type of the function is an object reference then there is a little
difference in the rule from java 1.5.
Example :
class
Alpha {
Alpha
doStuff(char c) {
return
new Alpha();
}
}
class
Beta extends Alpha {
Beta
doStuff(char c) { // legal override in Java 1.5
return
new Beta();
}
}
Here
doStuff(char c) is a legal override method if you are using java 1.5
or above for running it.From
java1.5 the return type must be the same as, or a subtype of, the
return type declared in the original overridden method in the
superclass.
Example:
class
Base{
public
void fun(){ //Line 2
}
}
class
Sub extends Base{
void fun(){ //Line 6
}
}
Here
you will get a compile-time error at Line 6 that Cannot reduce the
visibility of the inherited method from Base.The
access level can be less restrictive or same as that of the
overridden
method.
The
access level restrictions from high to low is
- private ( cant use for overriding)
- default or package level
- protected
- public
i.e.
If the base class method has default access then default,protected
and public access levels are valid for sub class function.In our
example you should use public access level for overriding method
fun().
class
Base{
public
void fun(){ //Line 2
}
}
class
Sub extends Base{
public void fun(){ //Line 6
}
}
4) Instance methods can be overridden only if they are inherited by the
subclass.
Remember
that overriding implies that you're reimplementing a method you
inherited.
A
subclass within the same package as the instance's superclass can
override any
superclass method that is not marked private or final.
class
Base{
private
void fun(){ //Line 2
}
}
class
Sub extends Base{
public void fun(){ //Line 6
}
}
The
above example is legal but Sub class fun() is not the overriding method of Base class fun() because private method fun() can’t be
inherited from Base to Sub class.
A subclass in a different package can override only those non-final methods marked public or protected (since protected methods are inherited by the subclass).
Package
p1;
Public
class Base{
void
fun(){ //Line 3
}
}
Package
p2;
Import
p1.Base;
class
Sub extends Base{
void
fun(){ //Line 4
}
}
The
above example is legal. But fun() in Sub is not the overriding
method of fun() in Base.Since the Base class fun() has package level
access ,it is not visible to package p2.
5) The overriding method CAN throw any unchecked (runtime) exception,regardless
of whether the overridden method declares the exception.
class
Base{
public
void fun(){ //Line 2
}
}
class
Sub extends Base{
public
void fun() throws ArithmeticException{
//Line 6
}
}
The
above example is valid because ArithmeticException
exception is a runtime exception.The overriding method can throw one
or more runtime exceptions even if the base class function is not
throwing it.
6) The overriding method must NOT throw checked exceptions that are new or
broader than those declared by the overridden method. The overriding
method can throw narrower or fewer exceptions.
Example:
class
Base{
public
void
fun() throws
IOException{
}
}
class
Sub1 extends
Base{
public
void
fun() throws
FileNotFoundException{
// Valid because FileNotFoundException is the sub class of IOException (narrowing).
// Valid because FileNotFoundException is the sub class of IOException (narrowing).
}
}
class
Sub2 extends
Base{
public
void
fun() throws
IOException{
//Valid because using same exception as that in base class function's throws clause.
//Valid because using same exception as that in base class function's throws clause.
}
}
class
Sub3 extends
Base{
public
void
fun(){
//Valid
because overriding method can throw fewer or no exceptions.
}
}
class
Sub4 extends
Base{
public
void
fun() throws
SQLException{
//Not valid because SQLException is a new exception .It is not compatible with IOException.
//Not valid because SQLException is a new exception .It is not compatible with IOException.
}
}
class
Sub5 extends
Base{
public
void
fun() throws
Exception{
//Not Valid because Exception is the base class of IOException (broadening).
//Not Valid because Exception is the base class of IOException (broadening).
}
}
7) You cannot override a method marked final.
class
Base{
final
public void fun(){ //Line 2
}
}
class
Sub extends Base{
public
void fun(){ //Line 6
}
}
You
will get compile-time error at Line 6 saying Cannot
override the final method from Base.
8) You cannot override a method marked static.
class
Base{
public
static
void
fun(){
}
}
class
Sub extends
Base{
public
static
void
fun(){
}
}
The
above example is valid but Sub class static fun() is not the
overriding method of Base class static fun().
Ie
Base b=new Sub();
b.fun();
Here
b.fun(); invokes the Base class fun() not the sub class fun() (in
case of non static method it will invoke Sub class fun() ).
Good explanation......
ReplyDelete