Java中多态的必要条件、缺点及解决缺陷方案(向下转型&instanceof 关键字) 多态的表现形式(重载)

本文深入解析Java中的多态概念,包括其必要条件、访问特点、优缺点及表现形式。探讨了父类引用指向子类对象时的行为差异,以及如何通过向上和向下转型解决多态带来的挑战。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

多态

同一个引用类型,使用不同的实例而执行不同操作,即父类引用指向子类对象

1.多态的必要条件

  1. 一定要有继承关系
  2. 一定要有重写
  3. 父类引用指向子类对象

2.访问多态成员的特点

  • 成员变量:编译时期看左边类型,运行时期看左边类型。(多态运用于行为,不是属性,所以和变量无关)

  • 成员方法:编译时期看左边类型,运行时期看右边类型。(虽然运行时期看右边类型,但因为子类方法通过父类方法重写的,所以父类方法不能删除【一定要有重写】)

  • 静态成员:编译时期看左边类型,运行时期看左边类型

            //static是不能继承的
            //所以Fu和Zi的method()是两个同名的方法,并不是重写
    
            public class DuoTaiDemo02 {
                public static void main(String[] args) {
                    Fu fu = new Zi();
                    fu.methed();
                    //The static method methed() from the type Fu should be accessed in a static way
                    //系统也不建议用对象调用静态方法,应该用类直接调用
                }
            }
    
            class Fu {
                public Fu() {}
                public static void methed() {
                    System.out.println("Fu staticMethod");
                }
            }
    
            class Zi extends Fu {
                public Zi() {}	
                public static void methed() {
                    System.out.println("Zi staticMethod");
                }
            }
    
  • 构造方法:先执行父类构造方法,加载父类静态成员,在执行子类构造方法

    • 可以加载父类的静态成员方法区
    • 帮助子类初始化从父类继承下来的成员

注意

私有方法 静态方法 final方法不能被继承,所以不能重写,不能构成多态,所以都是编译时期看左,运行时期看左,只有成员方法运行时期是看右的

3.多态的好处

  1. 简化代码
  2. 提高了代码维护性
  3. 提高了代码的扩展性

4.多态的缺点

多态的缺点:利用多态父类引用无法访问子类所特有的方法

        public class DuoTaiDemo04 {
            public static void main(String[] args) {
                Car c = new Bmw();

                c.run();
                c.showBrand();
                //The method showBrand() is undefined for the type Car
                //父类Car没办法识别方法showBrand()
                //因为父类没有这方法,遵循  2.访问多态成员的特点
                //成员方法:编译时期看左边类型,运行时期看右边类型
                //左边在编译时期并没有知道showBrand()方法,所报错
            }
        }

        class Car {
            public void run() {
                System.out.println("我也不知道怎么跑,想怎么跑就怎么跑!!");
            }
        }

        class Bmw extends Car {
            public void run() {
                System.out.println("嗖嗖搜地跑");
            }
            public void showBrand() {
                System.out.println("别摸我!");
            }
        }

解决方法: 向下转型 + i**nstanceof **关键字

4.1向上转型

        //格式
       		[父类类型] 引用变量名 = new [子类类型]( ) ;
4.1.1向上转型的特点
  1. 子类转化为父类,父类引用指向子类对象,类似于自动进行数据类型转换
  2. 通过父类引用变量调用的方法是子类覆盖或者继承父类的方法(多态的体现
  3. 通过父类引用变量无法调用子类特有的属性和方法(多态的缺点

4.2向下转型

        //格式
        	[子类类型] 引用变量名 = ( [子类类型] ) 父类引用变量名;
4.2.1向下转型的特点
  1. 父类转化为子类,父类引用转为子类对象,类似于强制类型转换

  2. 向下转换的过程中,子类类型与父类创建对象指向的子类类型不同时,会类型转换异常

            Car c = new Bmw();
            Benz benz = (Benz) c;//java.lang.ClassCastException
            //原因是向下转型的子类类型并不是创建对象时,父类引用指向的子类对象
            //即:c 指的是Bmw,而向下转型的子类类型是Benz
    

4.3instanceof 关键字

用于解决向下转型发生的类型转换异常

判断左边对象是否属于右边实例

        //格式
        	[对象] instanceof [];
			//返回值类型:boolean

4.4解决方式的缺陷

instanceof 解决类型转异常是有缺陷的

		if (c instanceof Bmw) {
			Bmw bmw = (Bmw) c;
			// 利用向下转型访问子类所特有的方法和属性
			bmw.showBrand();
		} else if (c instanceof Benz) {
			Benz benz = (Benz) c;
			benz.showSpeed();
		} else if (c instanceof Maslati) {
			Maslati maslati = (Maslati) c;
			maslati.showMoney();
		}
		//每当新建一个类,就需要增加一个else if
        //问题一:每次修改原码都必须进行测试
        //问题而:就算这可修改没什么问题不测试,对于有很多类的情况,就得大量加入else if,这工作量是不合理的

5.多态的表现形式(重载)

        //一个方法参数列表不同,在Test类中使用的时候,就可以根据多态调用同一个方法,不同的参数列表
        interface IPerson {
            void use(Student s);

            void use(Student s, Teacher t);

            void use(Teacher t, Student s);

            void use(Student s, Teacher t, Worker w);
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值