JAVA中多态性的理解(下)————多态性中的属性&方法

Source

JAVA中多态性的理解(下)————多态性中的属性&方法

大家好,作为一个刚开始接触写博客的计算机小白,写的内容是我在学习和理解过程中的一些想法,如果有不准确或者错误的地方麻烦大家指教【拱手】【拱手】



前言

首先回顾上一篇博客的内容,我们知道当对象有了多态性后,内存中实际上加载了子类的特有的属性和方法,但是由于变量声明为父类类型,所以导致在调用对象的属性和方法的时候,我们只能调用父类中声明过的属性和方法,导致子类特有的属性和方法不能够被调用,但如果我们想调用呢?其实是有方法的

第一种:强制数据类型转换(和基本数据类型转换想类似)
第二种:关键字instanceof的使用


一、强制类型转换的方法&错误类型

下面的代码是基于我上一篇博客中代码案例,进行增加修改,实现的对强制类型转换的实现以及错误的转换类型的分析

父类:Person
子类:Man,Woman
目的:实现多态性的强制类型转换

代码:

package com.HeZiHan.java;

public class DuoTaiZhuanHuan {
    
      //主类
	public static void main(String[] args) {
    
      
		//打印父类的eat方法    and	每一个子类重写后的eat方法
		Person p1 = new Person();
		p1.eat();
		
		Man m1 = new Man();
		m1.eat();
		
		Woman w1 = new Woman();
		w1.eat();
		
		System.out.println("************************************************");
		//打印进行多态化后的person的对象的eat方法
		Person p2 = new Man();
		p2.eat();
		
		Person p3 = new Woman();
		p3.eat();
		
		System.out.println("************************************************");
		//在主类中调用主类里的方法,但该方法也实现了多态化的使用
		//在该方法中,实参和形参在一起,相当于Person person = new Man();Person person = new Woman();
		DuoTaiZhuanHuan n =new DuoTaiZhuanHuan();
		n.show(new Man());
		n.show(new Woman());
		
		System.out.println("************************************************");
		System.out.println("分割线:上面是对多态性中方法调用的回顾,下面代码反映的是多态性中调用子类特有的方法和属性");
		//在上面的代码中我们知道,父类对象p2被赋值于子类Man;父类对象p3被赋值于子类Woman;
		//现在我们展示如何调用子类中特有的属性和方法,以及如何理解强制类型转换
		
		
		//Man m2=p2;-----------(×)
		//如果我们直接将父类对象p2直接转换为Man类型,虽然p2已经被Man经过多态性赋值,但P2本质上任然是Person类,而非Man类
		//所以我们如果想要调用P2中子类Man中所特有的属性和方法,就需要将它的类型进行转化
		
		Man m2 = (Man)p2;
		m2.eat();
		//首先我们需要知道,在上面的代码中,我们实现了将父类对象p2经过多态性将子类Man赋值于父类对象
		//此时我们将p2的类型转换为子类Man类型之后,用Man类型对象m2去接受,然后在通过调用m2的方法,实现调用p2中子类的方法
		
		System.out.println("************************************************");
		//错误的转换方式
//		Man m3 = (Man)p3;
//		m3.eat();
		
		//这里之所以会错是因为在类型转换的时候,类型不搭配导致的错误
		//我个人的理解是:首先p3已经在上面的代码中实现了被子类Woman赋值,那么在此时p3的内存中就包含了子类Woman的属性和方法,那么这个时候如果将它转变为Man类型,此时它的内存中并不包含Man特有的属性和方法,从而导致转换失败
		
		System.out.println("************************************************");
		//错误的转换方式
//		Person p4 = new Person();
//		Man m4 = (Man)p4;
//		m4.eat();
	
		//这里的错误类型和上述的错误类型相同
		//也可以这样想:如果我们将Person类型的p4装换为Man类型,此时p4对应的内存中并没有加载子类Man中的属性和方法,就算调用子类特殊的属性和方法,我们调用什么内容呢?里面都没有加载子类的属性和方法
		
		System.out.println("************************************************");
		//错误的转换方式
//		Person p5 = new Man();
//		Woman w2 = (Woman)p5;
//		w2.eat();
		
		//这里的错误类型与上述类型相同,即被转换对象内存中,并没有加载转目标类型中的属性和方法,从而导致转换失败
		
		
		
	}
	//主类中的一个方法
	public void show(Person person){
    
      
		person.eat();
		person.sleep();
	}
	
//	System.out.println("************************************************");
	//如果没有多态性的话,那么想要调用这个show方法就需要对这个方法进行多次重写,如下:
//	public void show(Man man){
    
      
//		man.eat();
//		man.sleep();
//	}
//	public void show(Woman woman){
    
      
//		woman.eat();
//		woman.sleep();
//    }
}
//父类Person
class Person {
    
      
	int age;
	double weight;
	
	public void eat(){
    
      
		System.out.println("人需要吃饭");
	}
	
	public void sleep(){
    
      
		System.out.println("人每天平均需要睡8小时");
	}
}
//子类Man
class Man extends Person{
    
      
	int houses;
	//对父类中的方法进行重写
	public void eat(){
    
      
		System.out.println("男人每天多吃肉");
	}
	public void sleep(){
    
      
		System.out.println("男人平均每天睡7小时");
	}
	
}
//子类Woman
class Woman extends Person{
    
      
	int car;
	//对父类中的方法重写
	public void eat(){
    
      
		System.out.println("女人每天多吃蔬菜");
	}
	public void sleep(){
    
      
		System.out.println("女人平均每天睡9小时");
	}
	
}

代码运行结果

人需要吃饭
男人每天多吃肉
女人每天多吃蔬菜
************************************************
男人每天多吃肉
女人每天多吃蔬菜
************************************************
男人每天多吃肉
男人平均每天睡7小时
女人每天多吃蔬菜
女人平均每天睡9小时
*****************错误类型①&正确的转换方式*******************************
分割线:上面是对多态性中方法调用的回顾,下面代码反映的是多态性中调用子类特有的方法和属性
男人每天多吃肉
*****************错误类型②*******************************
*****************错误类型③*******************************
*****************错误类型④******************************


二、强制类型转换方法——总结(一)


错误类型①:直接将父类对象转换为子类(一)
(没有加最基本的强制转换符)


在这里插入图片描述


错误类型②:不同类型之间的转换
(父类对象M被子类A类通过多态性赋值,但将M转换为子类B类)
在这里插入图片描述
在这里插入图片描述


错误类型③:父类直接强制转型为子类(二)
(此时的父类对象中并没有加载子类的任何属性方法,即使转换通过,那么要调用哪些子类中特有的属性和方法呢?内存中根本就没有可供调用的特殊的属性和方法)
在这里插入图片描述
在这里插入图片描述


错误类型④:同级子类之间的转化
(父类的两个子类之间相互转换,eg:上面的代码中将被Woman赋值过的p3强转为Man)
在这里插入图片描述
在这里插入图片描述


二、强制类型转换方法——总结(二)

①我们在实现将多态性中的类型强制性转换时,本质上是“向下转化”
②“父类 对象 = new 子类()”中右边子类是我们向下转换的最大限度
③自己总结的流程图,存在不足,希望谅解
在这里插入图片描述


三、关键字instanceof的使用

①“a instanceof A”判断对象a是否是类A的实例,如果是返回“True”,反之返回“Fasle”

②使用情况,我们在通过上面的强制类型转换可知,有时会出现强制转换类型失败,“ClassCastException”类型的错误,所以为了避免这种错误的出现,我们在向下转型之前,先进行instanceof的判断,一旦返回True,就向下转型,如果返回False,则不向下转型

③特例:如果a instanceof A 返回True,且a instanceof B 也返回True,则说明B是类A的父类


四、关于属性和方法在多态性中的调用总结

①若子类重写了父类的方法,就意味着子类定义的方法彻底覆盖了父类里同名的方法,运行看右边

②对于实例(对象)则不存在这样的情况,即使子类里定义了与父类完全相同的实例变量,这个实例变量依然不可能覆盖父类中定义的实例变量,编译看左边

在这里插入图片描述


五、结尾

感谢大家看到这里,这些就是我这个计算机小白的一些想法,如果有哪里出现了错误或者其他问题,欢迎大家指正,感谢感谢。