-
2021-02-28 11:46:46
Java多态之向下转型
往期回顾:我们学习了向上转型和动态绑定的概念,可以知道在继承关系中,将一个子类对象赋值给父类的引用变量,调用父类的方法,在实际运行时,就可以根据子类中重写的方法执行不同的操作。其中有一个弊端,就是在向上转型的过程中,其实丢失了一部分子类特有的功能,毕竟它只允许调用父类中的方法。那么,如何在这时调用子类中的方法呢,这时就需要与向上转型相对应的方法,就是所谓的:向下转型。
向上转型是自动就能完成的,向下转型则需要强制类型转换。
强制类型转换
我们前面提到过基本数据类型的强制转换,可以查看之前的文章:基本数据类型转换
引用变量的强制类型转换与基本数据类型类似,都需要用到类型转换运算符:()。
//将变量强制转换为type类型
type p = (type)变量
特别注意:
基本数据类型中,数值类型和布尔类型无法进行类型转换。
//错误!
boolean boo = true;
int in = (int)boo;
不在继承关系中的两个类型无法进行强制类型转换。
//假设Person类和Dog类不具有继承关系,则下面会出错
Person p = new Person();
Dog dog = (Dog)p;
就算在继承关系中,也不能把父类的实例转换成子类类型。(也就是说,引用变量必须编译时是父类类型,运行时是子类类型才可以)注意,编译时是不会报错的,只有运行时才会报错。
//假设Student继承于Person类
//编译时正常,运行时出错
Person p = new Person();
Student s = (Student)p;
instanceof
将一个父类引用赋给一个子类变量时,必须经过强制类型转换。如果出现强制类型转换双方不匹配的话,运行时通过(RTTI Run-Time Type Identification),即运行时类型识别,检查并返回ClassCastException,即类型转换异常。
为了避免这一尴尬的问题发生,我们可以用instanceof运算符来检查,确保程序的健壮性。
instance是实例的意思,可想而知,instanceof表示判断前面的对象是否是后面的类,或者子类,实现类的实例。如果是就返回true,否则就false。
[引用类型变量] instanceof [类(接口)]
从上面诸多错误例子中随便举一个:
//在强制类型转换前加上instanceof语句判断
Person p = new Person();
if (p instanceof Student) {
Student s = ((Student) p);
}
这时,if判断语句中为false,里面自然无法执行,也就避免程序报错,保证了程序的健壮性。
更多相关内容 -
java多态向下转型
2022-03-21 17:19:47什么是多态 简单的理解多态 多态,简而言之就是同一个行为具有多个不同表现形式或形态的能力。比如说,有一杯水,我不知道它是温的、冰的还是烫的,但是我一摸我就知道了。我摸水杯这个动作,对于不同温度的水,就...什么是多态
简单的理解多态
多态,简而言之就是同一个行为具有多个不同表现形式或形态的能力。比如说,有一杯水,我不知道它是温的、冰的还是烫的,但是我一摸我就知道了。我摸水杯这个动作,对于不同温度的水,就会得到不同的结果。这就是多态。
public class Water { public void showTem(){ System.out.println("我的温度是: 0度"); } } public class IceWater extends Water { public void showTem(){ System.out.println("我的温度是: 0度"); } } public class WarmWater extends Water { public void showTem(){ System.out.println("我的温度是: 40度"); } } public class HotWater extends Water { public void showTem(){ System.out.println("我的温度是: 100度"); } } public class TestWater{ public static void main(String[] args) { Water w = new WarmWater(); w.showTem(); w = new IceWater(); w.showTem(); w = new HotWater(); w.showTem(); } } //结果: //我的温度是: 40度 //我的温度是: 0度 //我的温度是: 100度
向上转型
子类引用的对象转换为父类类型称为向上转型。通俗地说就是是将子类对象转为父类对象。此处父类对象可以是接口。
案例驱动
看一个大家都知道的例子:
public class Animal { public void eat(){ System.out.println("animal eatting..."); } } public class Cat extends Animal{ public void eat(){ System.out.println("我吃鱼"); } } public class Dog extends Animal{ public void eat(){ System.out.println("我吃骨头"); } public void run(){ System.out.println("我会跑"); } } public class Main { public static void main(String[] args) { Animal animal = new Cat(); //向上转型 animal.eat(); animal = new Dog(); animal.eat(); } } //结果: //我吃鱼 //我吃骨头
这就是向上转型,Animal animal = new Cat();将子类对象Cat转化为父类对象Animal。这个时候animal这个引用调用的方法是子类方法。
转型过程中需要注意的问题
向上转型时,子类单独定义的方法会丢失。比如上面Dog类中定义的run方法,当animal引用指向Dog类实例时是访问不到run方法的,animal.run()会报错。
子类引用不能指向父类对象。Cat c = (Cat)new Animal()这样是不行的。向上转型的好处
- 减少重复代码,使代码变得简洁。
- 提高系统扩展性。
举个例子:比如我现在有很多种类的动物,要喂它们吃东西。如果不用向上转型,那我需要这样写:
public void eat(Cat c){ c.eat(); } public void eat(Dog d){ d.eat(); } //...... eat(new Cat()); eat(new Cat()); eat(new Dog()); //......
一种动物写一个方法,如果我有一万种动物,我就要写一万个方法,写完大概猴年马月都过了好几个了吧。好吧,你很厉害,你耐着性子写完了,以为可以放松一会了,突然又来了一种新的动物,你是不是又要单独为它写一个eat方法?开心了么?
那如果我使用向上转型呢?我只需要这样写:
public void eat(Animal a){ a.eat(); } eat(new Cat()); eat(new Cat()); eat(new Dog()); //.....
恩,搞定了。代码是不是简洁了许多?而且这个时候,如果我又有一种新的动物加进来,我只需要实现它自己的类,让他继承Animal就可以了,而不需要为它单独写一个eat方法。是不是提高了扩展性?
请等待下期向上转型
-
Java多态的向上转型和向下转型具体应用和意义以及instanceof使用
2021-05-21 19:10:16向上向下转型 定义一个父类Animals包含eat()方法、age初始值为0 然后再定义两个子类:Dog和Cat,都重写了eat()方法和age,然后再分别有自己的特有方法狗咆叫bark(),猫睡觉sleep() 向上转型:Animals a = new Cat() ...向上向下转型
定义一个父类
Animals
包含eat()
方法、age
初始值为0然后再定义两个子类:
Dog
和Cat
,都重写了eat()
方法和age
,然后再分别有自己的特有方法狗咆叫bark()
,猫睡觉sleep()
向上转型:
Animals a = new Cat()
向下转型:
Cat cat = (Cat) a
,必须要先经过向上转型的变量–再向下转型,此时cat
就拥有子类自己定义的特有方法cat.sleep()
instanceof
用法:a instanceof Cat
这里a
必须是经过向上转型后的父类对象,而Cat
是继承父类的子类// 父类 public class Animals { public int age = 0; public void eat(){ System.out.println("Eat..."); } } // 子类 继承 父类 Animals public class Dog extends Animals { public int age = 10; @Override public void eat(){ System.out.println("eat bone..."); } public void bark(){ System.out.println("dog bark..."); } } public class Cat extends Animals{ public int age = 2; @Override public void eat(){ System.out.println("eat fish..."); } public void sleep(){ System.out.println("cat sleep..."); } }
有一个宠物店
AnimalsShop
将宠物放入后,统计个数,以及可以取出该宠物public class AnimalsShop { // 注意这里用的Animals泛型,加入宠物时,不关心宠物的具体类型 private List<Animals> list = new ArrayList<Animals>(); // 当加入一个宠物时,相当于进行了向上转型 public void add(Animals a){ list.add(a); } public int getSize(){ return list.size(); } // 取出的宠物也是经过向上转型的,此时类型为Animals public Animals getAnimal(int position){ return list.get(position); } }
public static final int DOG = 0; public static final int CAT = 1; @Test public void test4(){ // 通过泛型进行向上转型将不同类型的动物加入集合,此时不需要动物的不同特性,只需要知道个数即可 AnimalsShop as = new AnimalsShop(); as.add(new Dog()); as.add(new Cat()); // 获取动物个数 System.out.println(as.getSize()); // 查看所有的宠物 Dog dog = (Dog) as.getAnimal(DOG); // 直接向下转型,并不安全,因为可以编译通过但运行出错 dog.eat(); dog.bark(); Animals a = as.getAnimal(CAT); // 获取已经向上转型Cat System.out.println(a instanceof Dog); // false,向上转型的Cat和Dog不构成子类关系 // ((已经经过向上转型的)父类对象 instanceof 子类 ) 来判断是否可以向下转型更安全,防止ClassCastException转换异常 if(a instanceof Cat){ Cat cat = (Cat) as.getAnimal(CAT); cat.eat(); cat.sleep(); } }
向下转型的最大好处是:java的泛型编程,用处很大,Java的集合类都是这样的。
参考博客多态的特点
多态的前提:
- 存在继承或实现接口
extend
或implement
- 重写方法
@Override
- 父类引用指向子类对象
Animals a = new Cat()
多态的特点:
- 相同变量看父类
a.age = 0
- 重写方法看子类
eat()看子类
- 子类特有方法不可用
a.sleep()不可用
public static void animalEat(Animals a){ a.eat(); } @Test public void test3(){ Animals a1 = new Dog(); System.out.println(a1.age); // 1. 变量看父类 a1.eat(); // 2. 方法看子类 // a1.bark(); 3. 子类特有不可用 Animals a2 = new Cat(); a2.eat(); // 当向上转型后,通过一个通用方法调用不同的子类,即可实现子类的方法 animalEat(new Dog()); animalEat(new Cat()); }
- 存在继承或实现接口
-
Java多态——向上、向下转型
2022-04-11 10:18:50Java多态——向上、向下转型Java多态——向上、向下转型
前言
为了解决代码的复用,提高扩展性
一、多态是什么?
同一个引用类型,使用不同的实例而执行不同操作。
二、多态的好处
1.解决代码复用
2.扩展性提高三、多态实现前提条件
1.多态实现必须有继承
2.有方法重写
3.父类引用指向子类对象(父类引用 赋值的子类对象)1、多态的两种体现形式
1)以父类类型作为方法的形参
代码如下(示例)://参数形式实现多态 public void feed(Pet pet){ //1.输出描述文字 System.out.println("小姑娘喂养宠物...."); //2.小狗吃东西 //Dog dog = new Dog(); //创建一个新的对象, 该方法每调用一次,产生一个对象 pet.eat(); }
//重写了父类的eat方法 @Override public void eat() { System.out.println("小狗吃狗粮....."); //加健康值与亲密度 //加健康值 + 10 在原来的健康值上加10 //this.getHealth() 获取它原来的值 this.setHealth(this.getHealth() + 10); //亲密度 + 5 this.setLove(this.getLove() + 5); }
2)以父类类型作为方法的返回值类型
public Pet lyPet(int num){ swich(num){ case 1: return new Dog(); case 2: return new Cat(); } return null; }
聚合
多态: 迟绑定,动态绑定
所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。
多态:父类引用指向子类对象 代码表示:
Pet pet=new Dog();
Pet pet=new Cat();
3)Pet pet = new Dog();与Dog dog = new Dog(); 的区别由于在编译阶段,只是检查参数的引用类型。然而在运行时, java虚拟机(JVM)指定对象的类型并且运行该对象的方法。 因此在下面的例子中, b.move()之所以能编译成功,是因为Pet类中存在move方法,所以编译成功,然而运行时, 运行的是特定对象的方法, 即运行的是Dog类的move方法。而对Dog c而言,编译阶段首先是去Dog中查找bark(), 因此能编译成功,同时也能运行成功;但是对于b.bark()而言,首先是去Pet类中寻找bark(), 因为找不到,因而编译错误。 public class Person { public static class Pet { public void eat() { System.out.println("Pet中的eat方法"); } } public static class Dog extends Pet{ public void eat() { System.out.println("dog中的eat方法"); } public void bark() { System.out.println("狗可以吠叫"); } } public static void main(String args[]) { Pet a = new Pet(); // Pet 对象 Pet b = new Dog(); // Dog 对象 Dog c = new Dog(); a.move();// 执行 Pet 类的方法 b.move();// 执行 Dog 类的方法 b.bark(); c.bark(); } }
四、向上转型
1)类结构图
父(辈)类类型 变量 接收一个子类对象, 把子类对象赋值给父类引用
向上转型,自动类型转换
2)优缺点
1.优点:实现多态
2.缺点:父类的引用调用不到子类特有的属性/方法public static void main(String[] args) { //使用子类对象接收 Dog dog = new Dog("旺财",70,50,"泰迪"); //dog调用特有属性方法 dog.setType("牧羊犬"); //没有问题 //向上转型: 把子类对象赋值给父类引用 Pet pet = dog; //使用父类引用调用子类特有属性方法 调用不到 //pet.setType("泰迪"); //报错 }
五、向下转型
1.语法
把父类转换为子类, 需要强制类型转换子类 子类变量名 = (子类名)父类对象;
2.目的
需要调用子类特有的属性和方法
3.instanceof使用
如果直接强制转换可能出现ClassCastException
从而就Java提供了instanceof
instanceof 使用场景, 当你需要向下转型的时候
java提供 instanceof对象 instanceof 类名/接口名
判断对象是否是右边的类或者接口的对象,或者是子类对象 结果: boolean ture: 表示对象是类的一个对象,或者子类对象 false 否则public static void main(String[] args) { Dog dog = new Dog(); Penguin penguin = new Penguin(); Pet p1 = penguin; System.out.println(dog instanceof Dog); //true System.out.println(dog instanceof Pet); //true System.out.println(penguin instanceof Penguin); //true System.out.println(penguin instanceof Pet); //true System.out.println(p1 instanceof Penguin); //true System.out.println(p1 instanceof Dog); //false System.out.println(p1 instanceof Pet); //true }
六、总结
1).多态的两种形式:
1.以父类类型作为方法的形参
2.以父类类型作为方法的返回值类型
2).向上转型:
可直接转但是不能 使用子类特有的属性和方法
3).向下转型
不能直接转,需要用到instanceof关键字,应用场景就是需要调用子类特有方法与属性 -
JAVA中多态以及向上转型向下转型、重写的讲解
2022-04-03 17:10:55对多态、、向上、向下转型,以及重写的解释 -
Java-多态的向上转型,向下转型
2022-03-21 17:19:13//向上转型 父类引用指向子类对象 //语法: 父类对象 引用变量名 = new 子类对象 Pet pet = new Dog(); //Pet(第一个Pet):父类对象 ... //向下转型:将一个指向子类对象的父类引用赋给一个子类的引用 . -
java多态(向上转型和向下转型)
2022-03-22 15:25:51在Java中,对于多态的核心表现主要有一下两点: 1.1 方法的多态性 ①. 方法的重载:同一个方法名称可以根据参数的类型或个数不同调用不同的方法体。 ②. 方法的覆写:同一个父类的方法,可能根据实例化子类的... -
Java - 多态之向上转型与向下转型
2021-12-13 20:43:56Java - 向上转型与向下转型 -
java的多态(向上转型、向下转型)
2017-08-27 18:59:19java的多态(向上转型、向下转型)在我的理解:java向上和向下转型可以看成是类型的转换。public class Person { public void eat(){ System.out.println("Person eatting..."); } public void sleep() { ... -
详解java多态中的向上转型,向下转型
2019-07-18 19:03:59#java多态概念: 多态是同一个行为具有多个不同表现形式或形态的能力。 多态就是同一个接口,使用不同的实例而执行不同操作。 多态性是对象多种表现形式的体现。 简单来说,多态就是利用父类对象调用子类对象中的... -
Java多态、向上转型、向下转型知识分享(讲解全面)
2022-02-21 17:43:19多态(方法的多态、对象的多态) 方法的多态 重写的多态(重要):子类继承父类,因此子类拥有父类属性和方法,如果子类重写父类方法,那么父类调用该方法的时候就会检查子类是否重写该方法,子类重写了就... -
Java 中多态的向下转型使用不当
2022-03-28 20:23:07/*多态的向下转型使用不当,程序运行时期异常 * * 在使用多态的向下转型:一定要看清楚此时内存是什么类型,否则就出现这个类转换异常 * */ //定义人类 class Person { public void study() { System.out.... -
Java多态——向上转型与向下转型
2017-07-05 20:14:13Java的转型之前一直处于似是而非的状态。 其中尤其是向上转型,大概意思谁不懂啊,A a = new B() 嘛,然而往细了抠就有点蒙蔽,尤其是面对考卷里出现的那种贼JB恶心的多态题,简直要哭了。 翻阅了几篇大佬们写的... -
关于Java多态下向上转型和向下转型的理解
2019-05-31 00:22:41刚接触Java,关于多态下向上转型和向下转型,以及父类和子类的调用很混乱,看了一天资料,终于搞明白了 关于多态向上转型和向下转型的要点 一、向上转型后子类不能调用自己的私有属性和私有方法,只能调用父类... -
Java多态中的向上转型和向下转型
2018-08-01 20:04:29向下转型:子类引用指向父类引用的子类对象 通俗的说就是子类实例对象赋值给父类引用,然后父类引用又要赋值给子类引用,这个过程就是向下转型。 语法: Father f = new Son(); Son s = (Son)f; //看语法... -
java多态的向上转型与向下转型(与编译时类型与运行时类型有关)
2020-08-06 16:41:30转载:java多态的向上转型与向下转型(与编译时类型与运行时类型有关) -
重新认识java(五) ---- 面向对象之多态(向上转型与向下转型)
2017-01-26 21:25:57多态,大概每个人都知道。但是,又有几个人真的理解什么是多态、多态有哪些细节呢?如果你看到这篇文章的名字,脑海中对多态没有一个清晰的概念,不妨点进来看看,也许会有收获。 -
java多态中的转型
2022-01-17 14:08:51作用 帮助实现子类特有的功能 分类 向上转型:从子到父,父类引用指向子类对象 向下转型:从父到子,父类引用转为子类对象 代码示例 动物类:包含eat()方法 public class Animal { public void eat(){ System.out.... -
Java概念:多态,向上转型,向下转型
2021-07-08 09:33:25多态(三大特征) 提高代码的复用性,利于代码的维护 方法的多态: 使用重载和重写可以实现多态 对象的多态:(重点) 一个对象的编译类型和运行类型可以不一致 编译类型在定义对象时,就确定了,不能改变 运行类型... -
多态中的向上转型与向下转型
2021-03-21 09:21:22在讨论向上转型和向下转型之前,先复习下多态。如果有错误的地方,希望能够指出,大家共同进步!什么是多态?多态(Polymorphism)即同一操作作用于不同的对象,可以有不同的解释,产生不同的结果。多态的分类多态一般... -
Java多态与向上向下转型
2022-04-18 20:00:42向上转型 多态的作用 1.增加代码的复用性 2.便于代码的管理与维护 案例引入 代码: //测试类 public class Test { public static void main(String[] args) { Dog dog = new Dog("八嘎"); Bone bone = new... -
Java多态(向上转型,向下转型,instanceof运算符)
2021-06-09 15:49:292.向下转型 父—>子(强制类型转换,需要加强制类型转换符) 无论是向上转型,还是向下转型,两种类型之间必须有继承关系,没有继承关系编译器报错。 什么是多态? 编译的时候是一种形态,运行的时候是另一种... -
Java笔记整理 —— 多态、向上转型、向下转型
2022-01-02 17:36:36多态 对于解决某些问题,比如 假设需要创建一个方法给宠物喂食,那么用传统方法来说,给猫喂鱼,狗喂骨头等等,需要每一个都写一个方法,这样导致代码的复用性不高,而且不利于代码的维护,因此需要多态。 多态... -
浅谈 --- Java中多态的向上转型和向下转型
2020-09-09 23:09:481. 什么是多态? 多态指的是同一个行为有多种不同的表现形式。 2. 构成多态的三个充要条件 继承。 重写父类方法。 父类引用指向子类的对象。 3. 代码分析 父类: package com.hfut; /** * @author Chenzh *... -
java多态向上转型和向下转型
2017-05-20 08:58:52interface Animal { int a = 1; int eat(); } public class Test implements Animal{ public static void main(String[] args) { //向上转型 Animal animal = new Test();... //向上转型后可以 -
Java基础 | 10.多态、向上转型、向下转型
2022-03-31 22:01:27向下转型 - 父类转换成子类3.instanceof 前置条件 有父类Animal,Cat是Animal的子类之一,即: // 父类:动物 public class Animal {...} // 子类:猫咪 public class Cat extends Animal {...} 1.向上转型 - 子类... -
Java接口,多态,向上转型,向下转型的意义
2020-10-14 17:18:06官方解释: Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现 ,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。 包含内容: (Java ... -
JAVA 多态(运行时多态和编译时多态)及其内存图解
2021-02-26 16:49:09定义:某一类事物的多种存在方式(一个对象,两种形态)对象的多态:父类或者接口的引用指向其子类的对象多态的好处:提高了代码的扩展性,前期定义的代码可以使用后期的内容多态弊端: 前期定义的内容不能使用(调用)... -
java多态性以及向上向下转型
2017-12-04 11:07:58向下转型: A a1 = new B() ; B b1 = (B)a1 ; A a2 = new A () ; B b2 = (B) a ;//编译正常,运行报错 这里A a1 = new B(),它在内存中的本质还是B类型,因为赋给A,所以只有A中的方法,能力弱化... -
秒懂Java多态的引用类型转换——向上转型、向下转型(强制转型)
2019-07-25 20:12:09多态的转型分为向上转型和向下转型两种 向上转型 多态本身是子类类型向父类类型向上转换的过程,这个过程是默认的。当父类引用指向一个子类对象时,便是向上转型。 使用格式: 父类类型 变量名 = new 子类类型();...