day12多态 抽象 接口 object

Day12

  1. 多态
    1.1 相关知识
  • JVM特性 : 多线程,跨平台,面向对象,自动垃圾回收机制
  • 面向对象特性 : 封装性,继承性,动态性(多态),抽象
  • 多态相关知识点 :
  •  软件设计六大原则	
    
  •  		里氏替换原则 : 能够使用父类的地方就一定可以使用子类
    
  •  			1 单一职责原则 : 功能职责单一,只拥抱一种变化
    
  •  			2 里氏替换原则 : 所有在使用父类的情况下,都可以使用子类
    
  •  			3 依赖倒置原则 : 高层通过抽象依赖底层,
    
  •  			4 接口隔离原则 : 不应该依赖于它不需要的接口
    
  •  			5 迪米特原则 : 最少知识原则
    
  •  			6 开闭原则 : 对扩展开放,对修改关闭
    

在这里插入图片描述

http://baijiahao.baidu.com/s?id=1645013441658118287&wfr=spider&for=pc

1.2 是什么

  • 多态就是里氏替换原则的一种体现

  • 什么是多态 : 父类引用 指向 子类对象

  •  	父类引用 : 父类型声明的引用类型变量
    
  •  	指向 : 就是通过这个引用类型的变量可以找到谁
    
  •  	子类对象 : new 的子类对象
    
  •  通过父类创建一个引用类型的变量,可以找到子类的对象
    
  •  	父类  变量  = new 子类();
    
  •  	Animal a = new Cat();
    
  • 变量声明 :

  •  	数据类型 变量名 = 值;
    
  • 变量分类 :

  •  	局部变量
    
  •  			1 方法内部声明
    
  •  			2 参数列表声明
    
  •  	静态变量
    
  •  	成员变量
    
  • 有变量的地方 就可以发生多态,并且多态是发生在赋值的时候

  •  Animal a  = new Cat();
    
  • 多态发生的几种形式

  •  	1 直接多态
    
  •  			不管成员变量还是局部变量 直接声明式多态 父类 变量 = new 子类();
    
  •  	2 形参和实参
    
  •  			方法参数定义时  使用父类定义,调用方法时,传递子类对象
    
  •  	3 返回值
    
  •  			返回值类型定义为父类, 返回数据的时候返回子类对象
    
  •  ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210117192349854.png)
    
  • 多态的缺点 : 丢失子类特有的属性

  • 多态调用属性 :

  •  	1 如果调用的是父类没有的,直接报错,都访问不了
    
  •  	2 如果调用的是子类没有的,都访问父类的
    
  •  	3 如果调用的是父类和子类都有的,那么除了成员方法调用子类的之外,其他的都调用父类的,因为成员方法可以覆写
    
  • 多态得到前提条件

  •  1 必须有继承关系的体系中(父,子,爷,孙 都可以)
    
  •  2 多态又叫向上转型
    

1.3 怎么用
在这里插入图片描述

在这里插入图片描述

1.4 为什么这么用(优点)

把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。

在这里插入图片描述

1.5 缺点(扩展)
丢失 子类特有的属性
为什么?

  • 多态缺点 丢失子类特有的属性,特有属性需要向下转型后 再进行访问
  • 并且 是编译时异常
  • 程序从开发到运行的完成生命周期
  •  编译阶段 : 在编译阶段的时候,父类文件有,子类文件也有,子类对象没有,但是我们在代码中已经定义了多态
    
  •  	这个时候,编译器会直接按照父类类型来划分空,来说明空间中有啥,来检查语法结构
    
  •  	这个时候 只能找到父类里面的属性说明,因为空间是父类声明的
    
  •  	什么时候有的子类对象? 运行时
    
  •  运行阶段
    
  •  	各个类载入方法区,开始运行,执行new 创建对象,对象用子类Cat创建的,所以 对象中是包含子类 特有属性的
    
  •  	但是引用变量的类型是父类类型,并且在编译时就已经进行了静态绑定,所以 使用这个父类声明的空间的时候就只能找到父类中有的
    
  •  	而 子类对象中 有的特有属性 是没有办法通过父类的变量找到的
    
  •  	因为 父类的变量声明的时候 只能够说明父类的属性列表,而创建对象之后,使用子类声明的属性值列表
    
  •  	按说 创建了对象,对象中有子类属性,为什么找不到? 因为在编译时就报错了,语句不通过,压根等不到运行时
    
  • 等于 使用父类的属性列表去调用 子类的属性值列表 是找不到
  • 编译时 :
  •  在编译的时候,会把父类的属性生成一个属性列表,父类属性有了,这叫编译时绑定,绑定完之后,程序就有了,属性就已经固定了
    
  •  属性值没有固定(都没有运行,没有空间,哪来的值?)
    
  •  这种编译时绑定,又可以叫做静态绑定/前绑定
    
  • 运行时 :
  •  运行的时候,把类生成对应的对象,也有了子类的属性列表,因为创建了对象,有了空间.进行了初始化操作,所以属性的值也就有了
    
  •  这种在运行阶段进行的数据绑定叫运行时绑定/动态绑定/后绑定
    
  • 调用时 :
  •  使用父类的引用,调用子类对象的属性的时候(特有的就访问不到了)
    
  •  也可以理解为 使用父类的属性列表 去调用子类的属性值列表
    
  •  所以问题就出现了,这样子类特有的就没有办法找到了
    

因为 使用的是父类的属性列表进行调用匹配,所以在找不到的时候语法就不通过了,所以在编译时就会报错,压根不能运行,不运行就没有对象,没有对象就更别提能不能找到特有数据了
*

  • super : 官方说法是 代表了父类型特征,这里就可以理解为父类的属性列表
  • 使用多态调用结果
  •  1 父类没有的,不管子类有没有 都调用不了,直接报错
    
  •  2 只要父类有的,子类没有的,都执行父类的
    
  •  3 父类和子类都有的时候,除了成员方法调用子类,其他都执行父类
    
  •  3 父类和子类都有的时候,除了成员方法调用子类,其他都执行父类
    
  •  3 父类和子类都有的时候,除了成员方法调用子类,其他都执行父类
    
  •  3 父类和子类都有的时候,除了成员方法调用子类,其他都执行父类
    

在这里插入图片描述

1.6 隐式多态(扩展)
* this : 谁调用,this就是谁 所以 这里this 一定是 subClass 这个子类对象
*
* this 是保存当前对象的内存地址,并且是第一个成员变量,既然是变量,那么总得有数据类型吧?
*
* this 用来存储当前对象的内存地址,那么 this的数据类型为 什么的时候 可以存储当前对象内存地址?
* 1 当前类类型
* 2 父类类型
* 如果是父类类型的话,就是多态,父类引用指向子类对象,缺点就是不能调用子类特有的属性,而 this 是可以调用当前类的特有属性的
* 所以 this的类型 是 当前类 类型
*
* 什么是当前类? : 当前类 就是 this所在的类(在哪个类出现的 ,哪个就是当前类)
*
* 那么 这里的this 就等于是 SupClass this
*
* 那么 this的引用 是子类对象,再结合this 是当前类类型 所以成了这样 SupClass this = new SubClass();

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

1.7 注意
在这里插入图片描述

以上这种,在第一行 p下面报错,一般是因为有类名冲突
可以检查一下 是否 存在 一个java文件中 创建了多个 class 并且有class同名
在这里插入图片描述

导包出错,傻眼了吧,因为当前包下,有一个和导入同名的类,就会出现这种问题

可以使用类全名解决

在这里插入图片描述

建议 不要和已有类同名,尤其是系统类

  1. Instanceof
  • 多态又叫向上转型,可以看做自动类型转换,从子类到父类
  • 向下转型,可以看做强制类型转换,从父类到子类,必须先发生向上转型
  • instanceof 判断该对象是否有某个类实例化而来

可以避免

在这里插入图片描述
在这里插入图片描述

  1. Abstract
    3.1 抽象概述

抽象类往往用来表示设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。
比如:动物,它只是一个抽象的概念,并没有一个 “东西”叫做 “动物”。所以,它并不能代表一个实体,这种情况下,我们就适合把它定义成抽象类。

  • abstract 是修饰符

  • 使用abstract 修饰的类,是抽象类

  • 使用abstract 修饰的方法,是抽象方法,抽象方法没有方法体,只有功能 定义,没有功能实现,用于让子类实现

  • 实现抽象方法,就是给抽象方法加上方法体,去掉abstract修饰

  • 抽象类的目的 : 该类不能被实例化对象,只能被继承

  • 抽象方法一定在抽象类 中,成立

  • 抽象类中一定有抽象方法,不成立,也可以没有,如果就想让某个类不能创建对象,也可以把该类创建类抽象类

  • final修饰的类不能被继承,

  • final修饰的成员方法不能被覆写

  • 而 抽象类 就是用于被继承的,抽象方法就是用于被实现覆写的

  • 所以 final 和 abstract 不能同时出现

  • 一个类 如果要继承一个抽象类,必须要实现该类的所有抽象方法

  • 一个抽象类 如果要继承一个抽象类 可以实现 0~N个抽象方法

3.2 怎么用

![在这里插入图片描述](https://img-blog.csdnimg.cn/20210117192622223.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1l6ajEyMzQ1NjEyNQ==,size_16,color_FFFFFF,t_70)

在这里插入图片描述

3.3 注意

在这里插入图片描述

  1. Interface
    4.1 是什么
  • 引用数据类型 : 类 数组 接口

  • 接口是一种引用数据类型,可以看做是一种特殊的类,是java为了解决没有多继承引起的功能变弱的问题

  •  一个类只能有一个父类,但是可以实现N个接口
    
  • 创建接口的方式 由 class 变成了 interface 而 父子关系 用 extends 变成了 implements

  • 类和类 使用extends,并且单继承

  • 类和接口 使用 implements 多实现 多个以逗号隔开,比如 class A implements V,C,D

  •  并且 非抽象类实现接口后,必须实现所有的抽象方法
    
  •  抽象类实现接口后 可以实现 0~N个抽象方法
    
  • 接口和接口 使用 extends,并且是多继承 比如 interface A extends B,C,D

  • 语法 :

  •  public  interface 接口名{
    
  •  }
    
  • 1 接口中 所有的变量 默认都是 public static final 的 也就是常量 ,而且 public static final 可以省略

  • 2 接口中的方法 默认都是 public abstract 的 也就是抽象方法,而且 public abstract 可以省略

  • 3 接口中没有构造方法,不能被实例化对象

  • 从 java1.8开始 接口中 可以有 默认方法和 静态方法

  • 接口可以看做是一个特殊的抽象类,所以很多时候 接口和抽象类都能做到某一件事

  • 优先使用接口,因为 类和接口之间是多实现, 当使用接口之后,还可以保留类的继承
    4.2 怎么用
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

4.3 接口和抽象类
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值