什么是多态?多态有哪些特点?多态的应用和好处有哪些?——多态
多态
概念
父类引用指向子类对象
父类类型的一个变量中存储了一个子类的对象
多态的理解
一个事物是什么取决于你认为它是什么(引用类型)
你认为的 ---> 引用类型
一个事物是什么 ----> 对象
多态的概念
- 属性没有多态(不研究)
- 成员方法具有多态
-(1)编译时多态————在编译时只能调用引用类型所对应类中声明的方法
-(2)运行时多态————在多态发生时,运行时调用的是子类重写父类后的方法实现 - 口诀
编译看左边 运行看右边
左边 = 右边
举例:
Animal animal = new Cat();
多态中类型之间的转换
-
对象一旦创建其类型不可以变
-
向上转型
将子类类型的对象引用,赋值给父类类型引用。
意义: 可以忽略 子类之间的差异,提升为父类类型进行统一的处理
- 向下转型
将父类类型的引用 赋值给子类的引用
意义: 恢复类子类原来的特征 通过向下转型 可以调用子类中特有的方法
类型转换异常
//Exception in thread "main" java.lang.ClassCastException: Demo1.Cat cannot be cast to Dmeo1.Dog
// at Demo1.main(Demo1.java:14)
当使用强制的方法进行转换的时候,可能会发生类型转换异常.
instanceof 语句(实例属于 )
-
语法
引用名 instanceof 类型
-
作用
判断一个引用中引用的对象是什么类型的数据
-
案例
package com.ujiuye.day10;
import java.util.Scanner;
public class Demo1 {
public static void main(String[] args) {
// Animal animal = new Cat();
//
// boolean f = animal instanceof Dog;// animal 变量中引用的对象的类型是否属于 dog 类型
// System.out.println(f);
Animal animal = new Dog();
if (animal instanceof Dog){
//进行向下转型
Dog dog = (Dog) animal;
dog.eat();
dog.sleep();
dog.shout();
}else{
Cat cat = (Cat) animal;
cat.eat();
cat.sleep();
cat.catchMouse();
}
}
}
//动物类
class Animal{
String name;
int age;
public void eat(){
System.out.println("动物吃");
}
public void sleep(){
System.out.println("动物睡觉");
}
}
//狗类
class Dog extends Animal{
//重写 父类中的方法
@Override
public void eat() {
System.out.println("狗汪汪汪的吃肉");
}
@Override
public void sleep() {
System.out.println("狗趴着睡觉");
}
//特有的方法
public void shout(){
System.out.println("狗汪汪汪的叫");
}
}
class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫喵喵的吃鱼");
}
@Override
public void sleep() {
System.out.println("猫 呼呼的睡觉");
}
//特有的功能
public void catchMouse(){
System.out.println("猫抓老鼠");
}
}
多态的应用
- 多态用在数组中
package com.ujiuye.day10;
import java.util.Scanner;
public class Demo1 {
public static void main(String[] args) {
//创建一个动物园
// zoo 里边 的每个元素的引用是什么类型 Animal 但是存放的是 子类对象 父类引用指向子类对象
Animal[] zoo = {
new Dog(),
new Cat(),
new Cat(),
new Wolf(),
new Wolf(),
new Wolf(),
new Wolf(),
new Monkey(),
new Monkey(),
};
//假设 现在动物园开饭了
//通过循环
for (int i = 0; i < zoo.length; i++) {
zoo[i].eat();
}
}
}
//动物类
class Animal{
public void eat(){
System.out.println("动物吃");
}
public void sleep(){
System.out.println("动物睡觉");
}
}
//狗类
class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗汪汪汪的吃肉");
}
//特有的方法
public void shout(){
System.out.println("狗汪汪汪的叫");
}
}
class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫喵喵的吃鱼");
}
//特有的功能
public void catchMouse(){
System.out.println("猫抓老鼠");
}
}
//猴子
class Monkey extends Animal{
@Override
public void eat() {
System.out.println("猴子吃桃");
}
}
//狼
class Wolf extends Animal{
@Override
public void eat() {
System.out.println("狼吃羊");
}
}
-
多态用在方法的参数上
-
多态用在方法的返回值上
举例:
有一个动物园,其中有很多动物, 找出其中所有的狗,进行获取,在主方法中,饲养狗
import java.util.Arrays;
import java.util.Scanner;
public class Demo1 {
public static void main(String[] args) {
Animal[] zoo = {
new Dog(),
new Dog(),
new Cat(),
new Wolf(),
new Wolf(),
new Wolf(),
new Monkey(),
new Monkey(),
new Monkey(),
new Monkey(),
new Monkey()
};
Dog[] dog = getDog(zoo);
//饲养所有的狗
for (int i = 0; i < dog.length; i++) {
dog[i].eat();
}
}
//方法一
// 方法名 : getDog 形式参数列表 Animal[] zoo 返回值类型 Dog[]
// public static Dog[] getDog(Animal[] zoo){
// //1 确定 动物园中有几只狗
// int dogCount = 0;
// for (int i = 0; i < zoo.length; i++) {
// //判断每只动物是否是狗
// if (zoo[i] instanceof Dog){
// dogCount++;
// }
// }
//
// //2 根据狗的个数确定狗窝的大小
// Dog[] dogsHouse = new Dog[dogCount];
//
// //3. 将所有的狗存储到狗窝中
// int index = 0;
// for (int i = 0; i < zoo.length; i++) {
// if (zoo[i] instanceof Dog){
// //向下转型
// dogsHouse[index] =(Dog) zoo[i];
// index++;
// }
// }
//
// //4 将狗窝返回
// return dogsHouse;
//
// }
//方法二
public static Dog[] getDog(Animal[] zoo){
//1 遍历每一个动物 判断是否为狗 是狗就存储到狗窝中
// 创建一个狗窝 容量为 0
Dog[] dogHouse = new Dog[0];
for (int i = 0; i < zoo.length; i++) {
if (zoo[i] instanceof Dog){
//存储到狗窝中
// 扩容
//dogHouse = dogHouseCopy(dogHouse);
dogHouse = Arrays.copyOf(dogHouse,dogHouse.length+1);
dogHouse[dogHouse.length-1] = (Dog) zoo[i];
}
}
return dogHouse;
}
//定义一个方法作用 是用于进行狗窝的扩容每次扩容 1
// public static Dog[] dogHouseCopy(Dog[] dogs){
// Dog[] newHouse = new Dog[dogs.length+1];
// //复制原来数组的元素
// for (int i = 0; i < dogs.length; i++) {
// newHouse[i] = dogs[i];
// }
// return newHouse;
// }
}
//动物类
class Animal{
public void eat(){
System.out.println("动物吃");
}
public void sleep(){
System.out.println("动物睡觉");
}
}
//狗类
class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗汪汪汪的吃肉");
}
//特有的方法
public void shout(){
System.out.println("狗汪汪汪的叫");
}
}
class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫喵喵的吃鱼");
}
//特有的功能
public void catchMouse(){
System.out.println("猫抓老鼠");
}
}
//猴子
class Monkey extends Animal{
@Override
public void eat() {
System.out.println("猴子吃桃");
}
}
//狼
class Wolf extends Animal{
@Override
public void eat() {
System.out.println("狼吃羊");
}
}
多态的好处
1.屏蔽⼦类之间的差异性
2.增强了⽅法的通⽤性
3.利于程序的扩展