面向对象的特征之三:继承性

面向对象的特征之三:继承性

目录

一、多态

1、为什么使用多态

2、什么是多态?

3、如何实现多态?

 二、向上转型

三、多态的使用案例

四、向下转型

 五、instanceof运算符

 六、多态的优势

七、面向对象编程

 八、本章总结


1. 理解多态性:可以理解为一个事物的多种形态
2. 何为多态性:
   1. 对象的多态性,父类的引用指向子类对象(或子类的对象赋值给父类的引用)
3. 多态性的使用,虚拟方法调用
   1. 有了对象的多态性以后,我们在编译器,只能调用父类中声明的方法,但在运行期间,我们实际上调用的是子类重写父类的方法。
   2. 总结:编译,看左边  运行,看右边
4. 多态性的使用前提:
   1. 要有类的继承性    
   2. 方法的重写
5. 对象的多态性:只适用于方法,不适用于属性(编译和运行都看左边)

一、多态

1、为什么使用多态

它能使同一个操作当作用于不同的对象,产生不同的执行结果。

使用多态可以提高代码的可维护性和可扩展性。

2、什么是多态?

  生活中的多态
       不同类型的打印机打印效果不同

      程序中的多态(父类引用指向子类对象
           同一个引用类型,使用不同的实例而执行不同操作,同一种操作,由于条件不同,产生的结果也不同。

3、如何实现多态?

实现多态的三要素

   继承关系的父类和子类(继承是多态的基础)
   子类重写父类方法
   父类的引用指向子类的对象 Crop crop=new Corn(); crop=new AppleTree();
多态的类型

    向上转型——子类到父类的转换:自动类型转换
    向下转型——父类到子类的转换:强制类型转换

 二、向上转型

将一个父类的引用指向一个子类对象称为向上转型

语法:

<父类型 > < 引用变量名 > = new < 子类型 >();
父类  变量名 =new 子类()

示例:

Crop crop = new AppleTree("富士"); //自动类型转换
crop.print(); //调用AppleTree类重写的print()方法

  系统会自动进行类型转换
  通过父类引用变量调用的方法是子类覆盖或继承的子类方法,不是父类的方法
  通过父类引用变量无法调用子类特有的方法

三、多态的使用案例

注意: 为了保证数据的一致性,要将父类对象定义为类的全局变量,使用父类对象作为方法形参时,通过父类引用变量,可调用子类中重写的方法
总结: 实现多态的2种方式
1. 父类引用指向子类对象
2. 父类为形参,子类为实参,以此实现多态

设计模式:
简单工厂设计模式——>抽象工厂

四、向下转型

问题:
  星沐生态农场”种植的作物,在生长以及采摘过程中,由于特殊情况,需要处理一些变化,要求:
    使用嫁接技术,将已种植的其他品种苹果转换为苹果新品种“红粉佳人”,后续也可以完成其他品种的嫁接
    如果玉米等作物赶上丰收年,需申请换用联合收割机,且变更收割费用为100元
分析:
  AppleTree类
  添加grafting(String newBread)方法,实现果树的嫁接功能
  Corn类
  添加reHarvester(double cost)方法,实现收割机变更功能
  测试类
  多态形式创建对象并调用
示例:
AppleTree苹果树类嫁接实现的关键代码:

//嫁接新品种
public void grafting(String newBrand) {
     if(this.brand == newBrand) {
         System.out.println("同品种果树无需嫁接。");
     } else {
         this.brand = newBrand;
         System.out.println("经过嫁接,"+super.getName() + "的品种变为"+this.brand+"。");
     }
}

Corn玉米类关键代码:

//更换收割机
public void reHarvester(double cost) {
      if(this.harvestCost == cost) {
       System.out.println("更换收割机后,费用不变!");
      } else {
       this.harvestCost = cost;
       System.out.println("更换收割机后,费用变为"+this.harvestCost+"。");
      }
}

Test类关键代码:

 问题: 如何才能使父类对象访问其子类特有的属性和方法呢

方案: 向下转型

  将一个指向子类对象的父类引用赋给一个子类的引用,即将父类类型转换为子类类型,称为向下转型向下转型必须进行强制类型转换
  将父类类型转换为它的某个子类类型后,才能调用其子类特有的属性
语法:

<< 子类型 > < 引用变量名 > = (< 子类型 >)< 父类型的引用变量 >

示例:

AppleTree appleTree =(AppleTree) crop; //将crop转换为AppleTree 类型
appleTree.grafting("粉红佳人"); //调用苹果树的嫁接方法

 五、instanceof运算符

  从父类到子类的向下转型,可以实现多态,即执行不同子类中定义的特定方法
  但事实上,父类对象的引用可能指向某一个子类对象
  如果在向下转型时,不是转换为真实的子类类型,就会出现转换异常
示例:

/**
 * ClaName:Test6
 * Description:TODO
 * date:2022/3/31 9:55
 *
 * @author Reincarnation
 * @version 1.0
 * @since JDK 1.8
 */
public class Test6 {
    public static void main(String[] args) {
        //创建一个农作物的数组
        Crop[] crops = new Crop[2];
        Crop crop = null;
        //在数组中初始化了两种农作物
        crops[0] = new AppleTree("富士");//苹果
        crops[1] = new Corn(50);//玉米

        //循环输出农作的个性化信息
        for (Crop model : crops) {
            model.print();
            AppleTree appleTree = (AppleTree) model;
            appleTree.grafting("蛇果");
        }
    }
}

JVM检测到两个类型间不兼容时,引发的运行时异常ClassCastException

注:构造函数没有数据

问题:如何通过代码避免这种异常的发生?
  使用instanceof运算符
用于判断一个对象是否属于一个类或者实现了一个接口
语法:

 对象 instanceof 类 | 接口  //运行结果为true或false


作用
  避免引发类型转换异常,提高代码的健壮性
应用场合
  向下转型之前,先使用instanceof进行类型判断

/**
 * ClaName:Test6
 * Description:TODO
 * date:2022/3/31 9:55
 *
 * @author Reincarnation
 * @version 1.0
 * @since JDK 1.8
 */
public class Test6 {
    public static void main(String[] args) {
        //创建一个农作物的数组
        Crop[] crops = new Crop[2];
        Crop crop = null;
        //在数组中初始化了两种农作物
        crops[0] = new AppleTree("富士");//苹果
        crops[1] = new Corn(50);//玉米
        //crops[0].grafting("红粉佳人");

        //解决问题
        for (Crop model : crops) {
            model.print();
            if (model instanceof AppleTree) {
                AppleTree appleTree = (AppleTree) model;
                appleTree.grafting("蛇果");
            } else if (model instanceof Corn) {
                Corn corn = (Corn) model;
                corn.reHarvester(100);
            }
        }
    }
}

注:构造函数没有数据

注意事项:

对象的类型必须与instanceof参数后所指定的类或接口在继承树上具有上下级关系;否则会出现编译错误


 六、多态的优势

七、面向对象编程

  面向对象的三大特性:封装、继承、多态
  封装是隐藏对象的属性和实现细节
​      将类的成员属性声明为私有的,同时提供公有的方法实现对该成员属性的存取操作
  继承是软件可重用性的一种表现
​      新类可以在不增加自身代码的情况下,通过从现有的类中继承其属性和方法充实自身内容
  多态是具有表现多种形态的能力的特征
​      在程序设计的术语中,意味着一个特定类型的变量可以引用不同类型的对象,自动地调用引用的对象的方法
​       即根据作用到的不同对象类型,响应不同的操作


 八、本章总结

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值