Java面向对象之多态、向上转型和向下转型


前言

 今天继续Java面向对象的学习,学习面向对象的第三大特征:多态,了解多态的意义,以及两种引用类型之间的转换:向上转型、向下转型。
 希望能对你的学习有所帮助!


提示:以下是本篇文章正文内容,Java系列学习将会持续更新

一、多态

(1)基本概念

多态就是指一个引用可以表示多种状态。意义在于实现参数统一化。

饮料:可乐、雪碧、红牛、美年达、…
宠物:狗、猫、鸟、…
整数: byte b = 10; short s = 10; int i = 10;…

C++多态分为两种:编译多态、运行时多态

Java的多态只有一种,就是运行时多态。是一种运行期间的行为,而不是编译期的行为。

(2)语法格式

  父类类型 引用 = new 子类类型();

 	Person ps = new Student();
 	ps.show();

解析:
  在编译阶段ps是Person类型,因此调用Person类自己的show()方法,若没有则编译的时候就报错。
  在运行阶段ps真正指向的对象是Student类型,因此最终调用的是Student类中自己的show()方法。

  当使用多态方式调用方法的时候,首先会检查父类中是否有该方法,如果没有,则编译报错。
  如果有,再去调用子类的同名方法。(注意:静态static方法属于特殊情况,静态方法只能继承,不能重写override,如果子类中定义了同名同形式的静态方法,它对父类方法只能起到隐藏的作用。调用的时候用谁的引用,则调用谁的版本。)

多态存在的三个比较条件:
  1.要有继承
  2.要有重写
  3.父类的引用指向子类的对象

(3)多态的效果

 1.对于指向子类对象的父类来说,在编译期间只能调用父类的方法,不能直接调用子类的方法。
 2.对于父子类都有的非静态方法来说,最终调用子类中的重写版本。
 3.对于父子类中都有的静态方法来说 ,最终调用父类中的版本,与指向的对象类型无关。

(4)案例

public class TestPersonStudent {
	public static void main(String[] args) {
	
		//使用父类的引用指向父类自己的对象
		Person p = new Person();
		p.show(); 
        /**
         * 运行结果:
         * 小白  18
         */
         
		//使用子类的引用指向子类自己的对象
		System.out.println("--------------------");
		Student s = new Student();
		s.show();
        /**
         * 运行结果:
         * 小白  18
         * 学号是1
         */
		
		//使用父类的引用指向子类的对象,形成多态
		System.out.println("--------------------");
		//发生由Student类型向Person类型的转换,小范围向大范围,自动类型转换
		Person ps = new Student("小黑",19,2);
		//解析:在编译期间调用的是Person.show(),在执行期间调用的是Student.show()
		ps.show();
		/**
         * 运行结果:
         * 小黑  19
         * 学号是2
         */
        
		//使用ps调用非静态方法进行测试
		System.out.println("--------------------");
		String str = ps.getName();
		//ps是Person类型的引用,因此可以调用Person类的方法
		System.out.println("获取到的名字是"+str);
		/*
		 * int num = ps.getId(); (X)
		 * 子类可访问调用父类的信息,但父类无法访问调用子类
		 */
		/**
         * 运行结果:
         * 获取到的名字是小黑
         */ 
        
		//使用ps调用静态方法进行测试
		System.out.println("--------------------");
		ps.test(); //警告
		Person.test(); //静态成员推荐使用类名.的方式访问
		//ps.test2(); (X)
		Student.test(); //当Student类中没有test()时,会自动调用父类中的test()
		Student.test2();
		/**
         * 运行结果:
         * Person类的静态方法
         * Person类的静态方法
         * Person类的静态方法
         * Student类的静态方法
         */
        
		//如何实现子类方法的调用
		System.out.println("--------------------");
		//由Person类型向Student类型的转换,大-》小,强制类型转换
		Student st = (Student) ps;
		int num = st.getId();
		System.out.println("ID是"+num);
        /**
         * 运行结果:
         * ID是2
         */
	}
}

回到目录…

二、引用类型之间的转换

(1)基本概念
  引用类型之间的转换必须发生在父子类之间,分为自动类型转换(向上转型)和强制类型转换(向下转型)。

Ⅰ.向上转型

父类引用指向子类对象:

Animal dog = new Dog();

把一个子类对象转换为父类对象,这种转型一共发生在三个地方:

①产生对象时

Animal animal = new Dog();

②方法参数传递

public void fun(Animal animal){}

fun(new Dog());

③方法返回值

public Animal test(){
   return new Dog();
}

注意:
  当执行animal.eat();时,因为new的是子类Dog,所以是运行子类重写父类的方法以及父类派生的方法,无法调用子类独有的方法。若子类没有重写,则调用父类的方法。
  父类中的静态方法无法被子类重写,所以向上转型之后只能调用父类原有的静态方法。

Ⅱ.向下转型

  子类引用指向父类实例,必须进行强制类型转换,可以调用子类特有的方法。

	Animal animal = new Bird();
	Bird bird = (Bird) animal;
	bird.fly();

这种转型有一定的风险性:

	Person ps = new Student(“小黑”,19,2);
	Teacher t = (Teacher)ps;  (X)

  当没有父子类关系发生强制类型转换则编译报错,当拥有父子类关系发生强制转换是编译通过;若目标类型并不是该引用真正指向的类型时,在运行阶段发生类型转换异常。

转型的前提:必须满足转型的条件

  为了避免上述错误的发生,通常只要进行强制类型转换就需要进行判断,格式如下:
if (引用变量名 instanceof 数据类型) {}

  instanceof 运算符可以进行判断,左侧对象是否满足右侧对象类型的特征。满足则返回true,否则返回false

 if(animal instanceof Bird){}

回到目录…


总结

提示:这里对文章进行总结:
以上就是今天的学习内容,本文是继续Java面向对象的学习,学习了多态、向上转型、向下转型,这些内容刚开始会觉得难理解,多写就会熟悉。之后的学习内容将持续更新!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只咸鱼。。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值