Dive into PIE - 'I', Part - 2

In our previous article, we have seen the basics of Inheritance. We have seen that we can use this concept to promote code re-usability.

But, we have not defined what inheritance is. So, let's start our discussion on this.

Essentially, Inheritance means an IS-A Relationship.

IS-A Relationship ! What is that now ?
An IS-A Relationship is used to determine that a particular Sub Class is also a Super Class.

Wait, wait, wait. How can a class be another class ?
Well, that's what a bit confusing when it starts. Now, let's take an example here. A very live implementation of inheritance is performed by nature itself.

How come ?
Back to our biology classes in our primary schools. We all know that, a Tree, a Dog, a Man, a Swan, a Crow etc. are living bodies while a Stone, a House, a Cycle etc. are non-living bodies.

So, what essentially differentiates these two is the behaviours of a living body and a non living body.

Hmm, exactly, living bodies has a set of some special behaviours that a non living body does not have. For example, breathing. We all know that all the living bodies breathe to live.

Correct you are. So, we know that a special feature of a living body is breathing. May be its a tree, a dog, a cat, a crow, a man or whatever you can think of living, it will definitely breathe. So, we can tell that a tree is a living body, a man is a living body, a dog is a living body and all of them breathe.

Right.

That is exactly what IS-A Relationship tells us.

Any particular subclass is also a super class.

Let's write an example of the same concept.

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");
 }
}

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.");
 }
}


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");
 }
}

So, in the previous example, we have depicted the eternal truth,

A HUMAN IS AN ANIMAL WHICH IS A LIVING BODY.

Now, in code also we can test the same. Let's try another example with the same classes associated,


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/*
 * 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) {
  Human human = new Human();
  System.out.println("A human is an animal: " + (human instanceof Animal));
  System.out.println("A human is a living body: " + (human instanceof LivingBody));
 }
}
When we run this code, it returns,

A human is an animal: true
A human is a living body: true

But, what is that instanceof  ?
instanceof  operator is used to test, whether an object is of the specified type (Class or Interface).
This is known as type comparison operator. We'll go deeper with instanceof operator in our subsequent sections. For now, simply remember that this operator is used to test IS-A Relationship.

Inheritance is applied to Interface as well ?
Yes, you pointed it correct, inheritance can be applied to Interfaces as well.

But how can an Interface promote code re-usability when it does not have any code in it ?
You are correct, Interfaces do not have any concrete implementation of any method. So, inheritance in interface is used for Agreement purpose. If you see in that article, you will notice that the Car interface was created to follow a particular contract which any Implemented Car must have to agree.

Hmm, I see that, Interface is being implemented in a class. But can we do the same thing in an interface as well ?
A good question. And the answer is YES, we can do that in interfaces as well.

Don't you think that it is unnecessary ?
An interface does nothing, so what would it do if it implements another interface ?

Think again...


Got it ?
No, I guess.

Well, an interface does not implement another interface, it basically extends another interface.

So, there goes a thumb rule,

1. A Class extends a Class.
2. A Class implements an Interface.
3. An Interface extends an Interface.
4. An Interface DOES NOT EXTEND A CLASS

And you can understand why an interface does not extend a class. The answer is quite simple, an interface does not do anything. So, interface extending a class is basically useless and it is prohibited in Java.

We have covered scenario 1 and 2 in our previous discussions. Let's take the third scenario.

What does an Interface do extending another Interface ?
Well, it basically reinforces the same contract of another interface. Let's take an example of the same,

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*
 * 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 26, 2015
 */
public interface Moveable {
 public void move();
}


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*
 * 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 26, 2015
 */
public interface Vehicle extends Moveable {
 public void getType();
}


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*
 * 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 26, 2015
 */
public interface Car extends Vehicle {
 public void accelerate();
}

In this example we can see that, Car is a Vehicle which is a Moveable.

So, let's decode this and understand what does it mean practically. It basically means that, a Car implementation must move(), must return its type by getType() and have to accelerate(). So, the Car interface basically reinforces the same contract which Vehicle and Moveable has already depicted.

Well, that's cool. But can't we add all the three methods in the same interface ?
To tell you the truth, yes it could be done. But we have divided it because, if we have to create a class other than car which also can move, then it is meaningless for that object to have accelerate() and getType() method. Let's take an example, if we have to create a Human object, we can put the restriction that a Human must know how to move, then we could write the following,
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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 implements Moveable {
 public void talk() {
  System.out.println("Human is talking");
 }

 /*
  * (non-Javadoc)
  * 
  * @see inheritance.Moveable#move()
  */
 @Override
 public void move() {
  System.out.println("Human is moving");
 }
}

So, you see how easily we have changed the definition of a Human.

If we moved everything in the Car Interface, it would not be easy to deal with.

Right.

Actually, the definitions of Classes and Interfaces are created by the System Designer in real time. So, as a developer you don't have to worry too much about these definitions. You simply have to follow according the existing design.

Well, another thing I have noted. The Human Class is extending Animal and also implementing Moveable ?
Yes, in Java we can do that. A Class can extend another class and Implement as many Interfaces as it wants to implement and that is allowed in Java and this concept is known ad Multiple Inheritance.

However, Java does not support extending multiple classes due to a Deadly Diamond of Death.
To know better, follow this topic http://java.palash90.in/2014/12/deadly-diamond-of-death.html

We now know that a class can extend another class and one or more interfaces. So, we can have the following definition and it is completely valid,
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/*
 * 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 26, 2015
 */
interface Blogger {
 public void writeBlog();
}

interface Professional {
 public void performJob();
}

interface SoftwareProfessional extends Professional {
 public void developSoftware();
}

public class Palash extends Human implements Blogger, SoftwareProfessional {

 /*
  * (non-Javadoc)
  * 
  * @see inheritance.SoftwareProfessional#developSoftware()
  */
 @Override
 public void developSoftware() {
  System.out.println("Palash is developing software");
 }

 /*
  * (non-Javadoc)
  * 
  * @see inheritance.Blogger#writeBlog()
  */
 @Override
 public void writeBlog() {
  System.out.println("Palash is writing blog");
 }

 /*
  * (non-Javadoc)
  * 
  * @see inheritance.Professional#performJob()
  */
 @Override
 public void performJob() {
  System.out.println("Palash is invoking developSoftware");
  developSoftware();
 }
}

So, from this definition, we can deduce the following,
  1. Palash is a Human
  2. Palash is an Animal
  3. Palash is a LivingBody
  4. Palash is a Blogger
  5. Palash is a Professional
  6. Palash is a SoftwareProfessional
Now, let's perform an instanceof test on an instance of Palash and see what happens,
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*
 * 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) {
  Palash palash = new Palash();

  System.out.println("Palash is a Human: " + (palash instanceof Human));
  System.out.println("Palash is an Animal: " + (palash instanceof Animal));
  System.out.println("Palash is a Living Body: " + (palash instanceof LivingBody));
  System.out.println("Palash is a Blogger: " + (palash instanceof Blogger));
  System.out.println("Palash is a Professional: " + (palash instanceof Professional));
  System.out.println("Palash is a Software Professional: " + (palash instanceof SoftwareProfessional));
 }
}

And when we run this code, we see the following,
Palash is a Human: true
Palash is an Animal: true
Palash is a Living Body: true
Palash is a Blogger: true
Palash is a Professional: true
Palash is a Software Professional: true

So, at any point of time, we an ask Palash to do any of the afore mentioned tasks that a Human, an Animal, a Living Body, a Blogger, a Professional or a Software Professional can do. So, the following invocations are also valid,
palash.breathe();
palash.developSoftware();
palash.eat();
palash.move();
palash.performJob();
palash.talk();
palash.writeBlog();

So, the following program is also valid,
/*
 * 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) {
  Palash palash = new Palash();
  
  palash.breathe();
  palash.developSoftware();
  palash.eat();
  palash.move();
  palash.performJob();
  palash.talk();
  palash.writeBlog();
 }
}

And when we run this program, we get the following output,

Living Body is breathing
Palash is developing software
Animal is eating.
Human is moving
Palash is invoking developSoftware
Palash is developing software
Human is talking
Palash is writing blog

Well, that's it. Now, we can conclude here. In our subsequent discussions, we'll see what we can do with Inheritance and what are the restrictions.

No comments:

Post a Comment