Thursday, December 4, 2014

Method Overriding

Method Overriding is the implementation of Runtime Polymorphism. When we want to implement some specific behaviour in Child Class, we use overriding.

Let's see how does it work,

We are now going into Java Code,

Let's first define the hierarchy,

LivingBody <- Animal <- Human <- Vegetarian
and
LivingBody <- Animal <-Horse

Now, consider the following,

package inheritance;
/*
 * Copyright 2014-2015 Palash Kanti Kundu.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @author Palash Kanti Kundu
 * @version 1.0
 * @since Dec 26, 2015
 */
public class LivingBody {
 public void breathe() {
  System.out.println("Living Body is breathing");
 }
}




And then we have Animal Class,

package inheritance;
/*
 * Copyright 2014-2015 Palash Kanti Kundu.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @author Palash Kanti Kundu
 * @version 1.0
 * @since Dec 26, 2015
 */
public class Animal extends LivingBody {
 public void eat() {
  System.out.println("Animal is eating.");
 }
}

Finally we have Human class,

package inheritance;
/*
 * Copyright 2014-2015 Palash Kanti Kundu.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @author Palash Kanti Kundu
 * @version 1.0
 * @since Dec 26, 2015
 */
public class Human extends Animal {
 public void talk() {
  System.out.println("Human is talking");
 }
 /*
  * (non-Javadoc)
  * 
  * @see inheritance.Animal#eat()
  */
 @Override
 public void eat() {
  System.out.println("Human is cooking food and eating");
 }
}

The code block is pretty simple, LivingBody has a generic implementation of breathe(). All LivingBodies breathe, Animal on the other hand has a specific behaviour, eat(). All animals eat. So, lets test this code first,

/*
 * Copyright 2014-2015 Palash Kanti Kundu.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package inheritance;
/**
 * Class to test inheritance.
 * 
 * @author Palash Kanti Kundu
 * @version 1.0
 * @since Dec 26, 2015
 */
public class InheritanceTest {
 public static void main(String[] args) {
  Animal animal = new Animal();
  animal.breathe();
  animal.eat();
 }
}

When we run this code, we get the following,


Living Body is breathing
Animal is eating.

Now, if we run the following code, it looks something different,

/*
 * Copyright 2014-2015 Palash Kanti Kundu.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package inheritance;
/**
 * Class to test inheritance.
 * 
 * @author Palash Kanti Kundu
 * @version 1.0
 * @since Dec 26, 2015
 */
public class InheritanceTest {
 public static void main(String[] args) {
  Animal animal = new Animal();
  Animal humanAnimal = new Human();
  animal.breathe();
  animal.eat();
  System.out.println();
  humanAnimal.breathe();
  humanAnimal.eat();
 }
}

This code output is however different from the previous one.


Living Body is breathing
Animal is eating.

Living Body is breathing
Human is cooking food and eating

So we see that, human eats in a different form than other animals do. So, human has a special behaviour for eating. And we have achieved through method overriding.
Now, let's make it more specific,

/*
 * Copyright 2014-2015 Palash Kanti Kundu.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package inheritance;
/**
 * @author Palash Kanti Kundu
 * @version 1.0
 * @since Dec 28, 2015
 */
public class Vegetarian extends Human {
 /*
  * (non-Javadoc)
  * 
  * @see inheritance.Human#eat()
  */
 @Override
 public void eat() {
  System.out.println("Vegetarians don't eat meat. I live on fresh vegetables.");
 }
}

Now, let's leverage the test again and see what happens,

/*
 * Copyright 2014-2015 Palash Kanti Kundu.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package inheritance;
/**
 * Class to test inheritance.
 * 
 * @author Palash Kanti Kundu
 * @version 1.0
 * @since Dec 26, 2015
 */
public class InheritanceTest {
 public static void main(String[] args) {
  Animal animal = new Animal();
  Animal humanAnimal = new Human();
  Animal vegetarian = new Vegetarian();
  animal.breathe();
  animal.eat();
  System.out.println();
  humanAnimal.breathe();
  humanAnimal.eat();
  System.out.println();
  vegetarian.breathe();
  vegetarian.eat();
 }
}

And the output is,
Living Body is breathing
Animal is eating.

Living Body is breathing
Human is cooking food and eating

Living Body is breathing
Vegetarians don't eat meat. I live on fresh vegetables.

Again, we create one more class and test the difference,

/*
 * Copyright 2014-2015 Palash Kanti Kundu.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package inheritance;
/**
 * @author Palash Kanti Kundu
 * @version 1.0
 * @since Dec 28, 2015
 */
public class Horse extends Animal {
}

/*
 * Copyright 2014-2015 Palash Kanti Kundu.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package inheritance;
/**
 * Class to test inheritance.
 * 
 * @author Palash Kanti Kundu
 * @version 1.0
 * @since Dec 26, 2015
 */
public class InheritanceTest {
 public static void main(String[] args) {
  Animal animal = new Animal();
  Animal humanAnimal = new Human();
  Animal horse = new Horse();
  Animal vegetarian = new Vegetarian();
  animal.breathe();
  animal.eat();
  System.out.println();
  horse.breathe();
  horse.eat();
  System.out.println();
  humanAnimal.breathe();
  humanAnimal.eat();
  System.out.println();
  vegetarian.breathe();
  vegetarian.eat();
 }
}
When we run this code, we can see the output as,
Living Body is breathing
Animal is eating.

Living Body is breathing
Animal is eating.

Living Body is breathing
Human is cooking food and eating

Living Body is breathing
Vegetarians don't eat meat. I live on fresh vegetables.
Now, see the difference, it has changed to human specific eating and vegetarian specific eating. But for Horse, it has not changed and by default the eat() method has been inherited to it.
But if you notice, in all the cases, the instance is of Animal Class and not a Human or Vegetarian Class and in all the cases, all the animals just breathe, may be it is an Animal, a Human or a Vegetarian, we do not see any change there.
So, the breathe method is inherited from LivingBody class and the eat method has been inherited to Horse from Animal but in case of Human the eat() method has been overridden for some specific stuff and in case of Vegetarian, it has been overridden from Human to do Vegetarian specific stuff.
So, if you have a specific behaviour in any class, you simply override the method with same signature and implement specific behaviour (in case of Human, Vegetarian). In other cases, the method is simply inherited from the parent class (in case of Horse).
That's it what Override looks like. However, there are some certain rules which are obvious in case of overriding and they goes as follows,

  • The argument list should be exactly the same as that of the overridden method. Because, if we change the method signature, it will become overloading and not overriding.
  • The return type should be the same or a subtype of the return type declared in the original overridden method in the superclass.
  • The access level cannot be more restrictive than the overridden method's access level. For example: if the superclass method is declared public then the overriding method in the sub class cannot be either private or protected.
    This one is required. Because, if you are trying to override a method and calling it with instance of Parent Class, the method must be visible according to the parent class.
  • Instance methods can be overridden only if they are inherited by the subclass. In other words, if the parent class method is private and in Child Class we are creating the method with same name and argument, it will be the Child Class Method.
  • A method declared final cannot be overridden. This is what final means.
  • A method declared static cannot be overridden but can be re-declared. Static methods are class specific and not instance specific. So, you cannot do that, if your redeclare, it will be the method for the Child Class.
  • If a method cannot be inherited, then it cannot be overridden. Simple, if you cannot use it, you probably cannot modify it.
  • A subclass within the same package as the instance's superclass can override any superclass method that is not declared private or final.
  • A subclass in a different package can only override the non-final methods declared public or protected.
  • An overriding method can throw any unchecked exceptions, regardless of whether the overridden method throws exceptions or not. However the overriding method should not throw checked exceptions that are new or broader than the ones declared by the overridden method. The overriding method can throw narrower or fewer exceptions than the overridden method.
  • Constructors cannot be overridden.

That's it follow these rules, implement specific behaviour in your child class and you are good to go with method overriding.

No comments:

Post a Comment