Polymorphism and downcasting in java


The content of the article is selected from Shang Silicon Valley, using the java8 environment

Detailed explanation of java object references

For a detailed explanation of java polymorphism, please see the previous blog: java polymorphism .

package com.atguigu.java4;

public class Person {
    
    
	String name;
	int age;
	int id = 1001;
	public void eat(){
    
    
		System.out.println("人吃饭");
	}
	public void walk(){
    
    
		System.out.println("人走路");
	}
}
package com.atguigu.java4;

public class Man extends Person {
    
    
	boolean isSmoking;
	int id = 1002;
	public void earnMoney(){
    
    
		System.out.println("男人挣钱");
		
	}
	public void eat(){
    
    
		System.out.println("男人吃饭");
	}
	public void walk(){
    
    
		System.out.println("男人走路");
	}
}
package com.atguigu.java4;

public class Woman extends Person {
    
    
	boolean isBeauty;
	
	public void eat(){
    
    
		System.out.println("女人吃饭");
		
	}
	public void walk(){
    
    
		System.out.println("女人走路");
	}
	public void goShopping(){
    
    
		System.out.println("女人爱逛街");
	}
}

When the code is executed

Person p2 = new Man();

When analyzing the memory of object attributes in java polymorphism, as shown in the figure.
Insert picture description here
Although p2 points to the heap space address of a Man object, it cannot allow p2 to call the unique attributes of the subclass.

//		p2.isSmoking = True;

Writing the compiler in this way will report an error. Although through analysis, the heap space object pointed to by p2 contains the isSmoking attribute, this object is a Man object after all, and cannot be attributed. In other words, p2 can only call the method of its declared type. And attributes.

The reference of the parent class calls the properties of the child class (downcast)

But if you want the parent class's reference (p2) to call the subclass's property (isSmoking), there is also a way to use coercive type conversion.

package com.atguigu.java4;

public class PersonTest {
    
    
	public static void main(String[] args) {
    
    
		Person p1 = new Person();
		Person p2 = new Man();
		p2.eat();
		System.out.println(p2.id);
//		p2.isSmoking = True;
		Man m1 = (Man)p2;
		m1.isSmoking = true;
		m1.earnMoney();
		System.out.println(m1.isSmoking);
	}
}

In this way, you can call the properties of the subclass, and the result of the operation is

Men eat
1001
men earn money
true

But its memory structure is that the m1 and p2 variables in the stack space all point to the address value of the same Man object, but since m1 is declared as a Man type, m1 can call the methods and properties of the heap space subclass. And p2 is declared as the Person class, which can only call the methods and properties in the parent class.

Make a comparison
with the forced type conversion and automatic type promotion of basic data types. The following figure directly adopts the figure of Shang Silicon Valley.
Insert picture description here
However, forced type conversion cannot be used casually. Sometimes the compiler does not report an error, but a ClassCastException type conversion exception will occur during operation.

package com.atguigu.java4;

public class PersonTest {
    
    
	public static void main(String[] args) {
    
    
		Person p2 = new Man();
		Man m1 = (Man)p2;
		m1.isSmoking = true;
		Woman w1 = (Woman)p2;
		w1.goShopping();
		
	}
}

The result of the operation is

Exception in thread “main” java.lang.ClassCastException: com.atguigu.java4.Man cannot be cast to com.atguigu.java4.Woman
at com.atguigu.java4.PersonTest.main(PersonTest.java:8)

This is because the heap space pointed to by p2 itself does not have the goshopping method.
Therefore, in order to ensure the success of the conversion, the instanceof keyword is introduced when the type conversion is performed.

Usage of instanceof keyword

  • The usage is a instanceof A, to determine whether the a object is an instance of class A, return true if it is, and false if it is not
  • If a instanceof A returns true, and B is the parent of A, then a instanceof B also returns true.

code show as below

package com.atguigu.java4;

public class PersonTest {
    
    
	public static void main(String[] args) {
    
    
		Person p2 = new Man();
		
		if(p2 instanceof Woman){
    
    
			Woman w1 = (Woman)p2;
			w1.goShopping();
			System.out.println("***woman****");
		}
		if(p2 instanceof Man){
    
    
			Man m1 = (Man)p2;
			m1.earnMoney();
			System.out.println("***man****");
		}
		
	}
}

The result of the operation is

Man earns money
man *

Special emphasis on p2 instanceof Man is to see whether the heap space object pointed to by p2 is a Man object
because

Person p2 = new Man();

When using polymorphism, a Man object of the p2 class pointing to the heap space has been declared, so the return value of p2 instanceof Man is true. In this way, it is avoided that the ClassCastException type conversion exception that occurs when the method and properties of the subclass are called from the reference of the parent class by the use of forced type conversion.

Guess you like

Origin blog.csdn.net/Meloneating/article/details/113780846
Recommended