More on Inheritance & Subtyping polymorphism
Overview
Let' see some examples of various cases of Inheritance & polymorphism.
Example - 1 (Very basic)
1class A {
2
3 public void func() {
4
5 System.out.println("Class A's func");
6 }
7
8 public void foo() {
9
10 System.out.println("Class A's foo");
11 }
12}
1class Helper {
2
3 public static void main(String args[]) {
4
5 A a = new A();
6 a.foo();
7 a.func();
8 }
9}
1Class A's foo
2Class A's func()
- foo() is defined in class A. We are creating an object of class A and using reference type of class A only.
a
will be able to access foo() and printClass A's foo
- The same logic applies for func()
Example 2
1class A {
2
3 public void func() {
4
5 System.out.println("Class A's func");
6 }
7
8 public void foo() {
9
10 System.out.println("Class A's foo");
11 }
12}
1class B extends A {
2
3 public void bar() {
4
5 System.out.println("Class B's bar");
6 }
7}
1class Helper {
2
3 public static void main(String args[]) {
4
5 B b = new B();
6 b.foo();
7 b.func();
8 b.bar();
9 }
10}
1Class A's foo
2Class A's func
3Class B's bar
- foo() is defined in class A. We are creating an object of class B and using reference type of class B only.
b
will be able to access foo() through inheritance and printClass A's foo
- func() is defined in class A. We are creating an object of class B and using reference type of class B only.
b
will be able to access func() through inheritance and printClass A's func
- bar() is defined in class B. We are creating an object of class B and using reference type of class B only.
b
will be able to access bar() and printClass B's bar
Example 3
1class A {
2
3 public void func() {
4
5 System.out.println("Class A's func");
6 }
7
8 public void foo() {
9
10 System.out.println("Class A's foo");
11 }
12}
1class B extends A {
2
3 public void bar() {
4
5 System.out.println("Class B's bar");
6 }
7}
1class Helper {
2
3 public static void main(String args[]) {
4
5 A a = new B();
6 a.foo();
7 a.func();
8 //a.bar();
9 }
10}
1Class A's foo
2Class A's func
- foo() is defined in class A. We are creating an object of class B and using reference type of class A.
a
will be able to access foo() through inheritance and printClass A's foo
- func() is defined in class A. We are creating an object of class B and using reference type of class A.
a
will be able to access func() through inheritance and printClass A's func
- What if I try to print
a.bar()
? Now notice where arrow is pointed to in the figure above. bar() is not defined in class A. So even if I've created an object of class B, I will not be able to access bar() method from reference type of class A.a.bar()
will throw me error! (Something new)
Example 4
1class A {
2
3 public void func() {
4
5 System.out.println("Class A's func");
6 }
7
8 public void foo() {
9
10 System.out.println("Class A's foo");
11 }
12}
1class B extends A {
2
3 public void bar() {
4
5 System.out.println("Class B's bar");
6 }
7 public void func() {
8
9 System.out.println("Class B's func");
10 }
11}
1class Helper {
2
3 public static void main(String args[]) {
4
5 B b = new B();
6 b.foo();
7 b.func();
8 b.bar();
9 }
10}
1Class A's foo
2Class B's func
3Class B's bar
- foo() is defined in class A. We are creating an object of class B and using reference type of class B.
b
will be able to access foo() through inheritance and printClass A's foo
- func() is defined in class A and also overridden in B. We are creating an object of class B and using reference type of class B.
b
will be able to access func() and printClass B's func
- bar() is defined in class B. We are creating an object of class B and using reference type of class B only.
b
will be able to access bar() and printClass B's bar
Example 5
1class A {
2
3 public void func() {
4
5 System.out.println("Class A's func");
6 }
7
8 public void foo() {
9
10 System.out.println("Class A's foo");
11 }
12}
1class B extends A {
2
3 public void bar() {
4
5 System.out.println("Class B's bar");
6 }
7 public void func() {
8
9 System.out.println("Class B's func");
10 }
11}
1class Helper {
2
3 public static void main(String args[]) {
4
5 A a = new B();
6 a.foo();
7 a.func();
8 //a.bar();
9 }
10}
1Class A's foo
2Class B's func
- foo() is defined in class A. We are creating an object of class B and using reference type of class A.
a
will be able to access foo() through inheritance and printClass A's foo
- func() is defined in class A and also overridden in B. We are creating an object of class B and using reference type of class A.
a
will be able to access func(). You might be tempted to say that it'll printClass A's func
but it will be wrong. Visually, it will follow the arrows and printClass B's func
- Still the same logic applies for
a.bar()
(as example 3). Reference of type A will not be able to accessbar()
Example 6
1class A {
2
3 public int a;
4}
1class B extends A {
2
3 public int b;
4}
1class Helper {
2
3 public static void main(String args[]) {
4
5 B bObject = new B();
6 bObject.a = 1;
7 bObject.b = 2;
8
9 System.out.println("a: " + bObject.a);
10 System.out.println("b: " + bObject.b);
11 }
12}
1a: 1
2b: 2
a
is an instance variable defined in class A. We are creating an objectbObject
of class B and using reference type of class B only to refer it.a
will be available in class B through inheritance and we will be able to printa: 1
b
is an instance variable of class B itself, so this shouldn't be a problem.
Example 7
1class A {
2
3 public int a;
4}
1class B extends A {
2
3 public int b;
4}
1class Helper {
2
3 public static void main(String args[]) {
4
5 A aObject = new B();
6 aObject.a = 1;
7 //aObject.b = 2;
8
9 System.out.println("a: " + aObject.a);
10 //System.out.println("b: " + aObject.b);
11 }
12}
1a: 1
a
is an instance variable defined in class A. We are creating an objectaObject
of class B and using reference type of class B only to refer it.a
will be available in class B through inheritance and we will be able to printa: 1
b
is an instance variable of class B. We are creating an objectaObject
of class B and using reference type of class A to refer it. It won't be visible to class A and hence it will throw errors (similar logic as example 3)
Example 8 (hiding variable)
1class A {
2
3 public int a = 0;
4}
1class B extends A {
2
3 public int a = 1;
4}
1class Helper {
2
3 public static void main(String args[]) {
4
5 B bObject = new B();
6 A aObject = new A();
7
8 System.out.println("Output 1: " + bObject.a);
9 System.out.println("Output 2: " + aObject.a);
10 }
11}
1
as we've overridden a
instance variable in B. Let's look at it visually:
Let's look at it visually:
Output:
1Output 1: 1
2Output 2: 0
a
, or the scoped name this.a
, within the class, we are referring to the field that is defined in B.
As for the second line: There is no polymorphism for fields in Java so accessing a
using class A reference, even though we are creating an object of class B, will point to class A's instance variable only.
Takeaways
- You can call a method on an object only if the class of the reference variable has that method.
- No polymorphism when it comes to instance variables
Acknowledgements
- https://stackoverflow.com/questions/15513467/polymorphism-with-instance-variables
- https://stackoverflow.com/questions/10722110/overriding-member-variables-in-java-variable-hiding