八、面向对象进阶三
什么是多态?
-
同类型的对象,执行同一个行为,会表现出不同的行为特征
多态的常见形式
-
父类类型 对象名称 = new 子类构造器;
-
接口 对象名称 = new 实现类构造器;
多态中成员访问特点
-
方法调用:编译看左边,运行看右边
-
变量调用:编译看左边,运行也看左边(多态侧重行为多态)
多态的前提
-
有继承/实现关系;有父类引用指向子类对象;有方法重写。
多态的优势
-
在多态形势下,右边对象可以实现解耦合,便于扩展和维护
-
定义方法的时候,使用父类型作为参数,该方法就可以接收这父类的一切子类对象,体现出多态的扩展性和便利
多态下会产生的一个问题:
-
多态下不能使用子类的独有功能
多态类型转换
-
自动类型转换(从子到父):子类对象赋值给父类类型的变量指向
-
强制类型转换(从父到子):
-
此时必须进行强制类型转换:子类 对象变量 = (子类) 父类类型的变量
-
作用:可以解决多态下的劣势,可以实现调用子类独有的功能
-
注意:如果转型后的类型和对象真实类型不是同一种类型,那么在转换的时候就会出现ClassCastException
-
Java建议强转转换前使用instanceof判断当前对象的真实类型,在进行强制转换
-
变量名 instanceof 真实类型
-
判断关键字左边的变量指向的对象的真实类型,是否是右边的类型或者是其子类类型,是则返回:true,反之
-
-
内部类
-
内部类就是定义在一个类里面的类,里面的类可以理解成(寄生),外部类可以理解成(宿主)
-
格式:
-
public class People{
-
public class Heart{}}
-
-
-
-
内部类的使用场景、作用
-
当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构可以选择使用内部类来设计。
-
内部类通常可以方便访问外部类的成员,包括私有的成员
-
内部类提供了更好的封装性,内部类本身就可以用private protectecd等修饰,封装性可以做更多控制。
-
-
内部类的分类
-
静态内部类【了解】
-
有static修饰,属于外部类本身
-
它的特点和使用与普通类是完全一样的,类有的成分它都有,只是位置在别人里面而已。
-
public class Outer{
-
//静态成员内部类
-
public static class Inner{}}
-
-
静态内部类创建对象的格式:
-
格式:外部类名.内部类名 对象名 = new 外部类名.内部类构造器;
-
范例:Outer.Inner in = new Outer.Inner();
-
-
静态内部类的访问拓展:
-
静态内部类中是否可以直接访问外部类的静态成员?
-
可以,外部类的静态成员只有一份可以被共享访问
-
-
静态内部类中是否可以直接访问外部类的实例成员?
-
不可以,外部类的实例成员必须用外部类对象访问
-
-
-
-
成员内部类【非静态内部类】【了解】
-
什么是成员内部类?
-
无static修饰,属于外部类的对象。
-
JDK16之前,成员内部类中不能定义静态成员,JDK16开始也可以定义静态成员了。
-
public class Outer{
-
//成员内部类
-
public class Inner{}}
-
-
-
-
成员内部类创建对象的格式:
-
格式:外部类名.内部类名 对象名 = new 外部构造器().new 内部构造器();
-
范例:Outer.Inner in = new Outer().new Inner();
-
-
成员内部类的访问拓展:
-
成员内部类中是否可以直接访问外部类的静态成员?
-
可以,外部类的静态成员只有一份可以被共享访问。
-
-
成员内部类的实例方法中是否可以直接访问外部类的实例成员?
-
可以,因为必须先有外部类对象,才能有成员内部类对象,所以可以直接访问外部类对象的实例成员
-
-
-
注意:在成员内部类中访问所在外部类对象,格式:外部类名.this
-
-
局部内部类【了解】
-
局部内部类(鸡肋语法,了解即可)
-
局部内部类放在方法、代码块、构造器等执行体中
-
局部内部类的类文件名为:外部类$N内部类.class
-
-
-
匿名内部类【重点】
-
本质上是一个没有名字的局部内部类,定义在方法中、代码块中等
-
作用: 方便创建子类对象,最终目的为了简化代码编写
-
格式:
-
new 类|抽象方法|或者接口名(){
-
重写方法;};
-
-
-
范例:Employee a = new Employee(){
-
public void work(){}};
-
a.work();
-
-
-
特点总结:
-
匿名内部类是一个没有名字的内部类
-
匿名内部类写出来就会产生一个匿名内部类的对象
-
匿名内部类的对象类型相当于是当前new的那个的类型的子类类型
-
匿名内部类可以作为方法的实际参数进行传输
-
开发中不是我们主动去定义匿名内部类的,而是别人需要我们写或者我们可以写的时候才会使用。匿名内部类的代码可以实现代码进一步的简化(回扣主题)
-
-
-
什么是API?
-
API(Application Programming interface)应用程序编程接口。
-
简单来说:就是Java帮我们已经写好的一些方法,我们直接拿过来用就可以了
-
Object类的作用:
-
一个类要么默认继承了Object类,要么间接继承了Object类,Object是Java中的祖宗类
-
Object类的方法是一切子类都可以直接使用的,所以我们要学习Object类的方法
-
-
Object类的常用方法:
-
方法名 说明 pubilc String toString() 默认是返回当前对象在堆内存中的地址信息:类的全限名@内存地址 public Boolean equals(Object o) 默认是比较当前对象与另一个对象的地址是否相同,相同返回true,不同返回false -
Object的equals方法的作用是什么?
-
默认是与另一个对象比较地址是否一样
-
让子类重写,以便比较2个子类对象的内容是否相同
-
-
Objects概述
-
Objects类与Object还是继承关系,Objects类是从JDK1.7开始之后才有的
-
官方在进行字符串比较时,没有用对象自己的equals方法,而是选择了Objects的equals方法来比较两个对象
-
Objects的equals方法比较的结果是一样的,但是更安全
-
Objects的常见方法:
-
方法名 说明 public static boolean equals(Object a,Object b) 比较两个对象的,底层会先进行非空判断,从而可以避免空指针异常。在进行equals比较 public static boolean isNull(Object obj) 判断变量是否为null,为null返回true,反之
-
-
-
对象进行内容比较的时候建议使用什么?为什么?
-
建议使用Objects提供的equals方法
-
比较的结果是一样的,但是更安全
-
-
-
StringBuilder概述
-
StringBuilder是一个可变的字符串类,我们可以把它看成是一个对象容器
-
作用:提高字符串的操作效率,如拼接、修改等
-
-
StringBuilder构造器
-
名称 说明 public StringBuilder() 创建一个空白的可变的字符串对象,不包含任何内容 public StringBuilder(String str) 创建一个指定字符串内容的可变字符串对象
-
-
StringBuilder常用方法
-
方法名称 说明 public StringBuilder append(任意类型) 添加数据并返回StringBuilder对象本身 public StringBuilder reverse() 将对象的内容反转 public int length() 返回对象内容长度 public String toString() 通过toStrign()就可以实现把StringBuilder转换为String
-
-
Math类
-
包含执行基本数字运算的方法,Math类没有提供公开的构造器。
-
如何使用类中成员呢?
-
看类的成员是否都是静态的,如果是,通过类名就可以直接调用
-
-
Math类的常用方法
-
方法名 说明 public static int abs(int a) 获取参数绝对值 public static double ceil(double a) 向上取整 public static double floor(double a) 向下取整 public static int round(float a) 四舍五入 public static int max(int a, int b) 获取两个int值中的较大值 public static double pow(double a,double b) 返回a的b次幂的值 public static double random() 返回值为double的随机值,范围[0.0,1.0]
-
-
-
System类概述
-
System的功能是通用的,都是直接用类名调用即可,所以System不能被实例化
-
System类的常用方法
-
方法名 说明 public static void exit(int status) 终止当前运行的Java虚拟机,非零表示异常终止 public static long currentTimeMillis() 返回当前系统的时间毫秒值形式 public static void arraycopy(数据源数组,起始索引,目的地数组,起始索引,拷贝个数) 数组拷贝
-
-
-
时间毫秒值
-
计算机认为时间是有起点的,起始时间:1970年1月1日 00:00:00
-
时间毫秒值:指的是从1970年1月1日 00:00:00走到此刻的总的毫秒数,应该是很大的 1s = 1000ms
-
原因:
-
1969年8月,贝尔实验室的程序员肯汤普逊利用妻儿离开一个月的机会,开始着手创造一个全新的革命性的操作系统,他使用B编译语言在老旧的PDP-7机器上开发出了Unix的一个版本,随后,汤普逊和同事丹尼斯里奇改进了B语言,开发了C语言,重写了UNIX。所以1970年1月1日 算C语言的生日
-
-
-
BigDecimal作用
-
用于解决浮点型运算精度失真的问题
-
使用步骤:
-
创建对象BigDecimal封装浮点型数据(最好的方式是调用方法)
-
public static BigDecimal valueOf(double val): 包装浮点数成为BigDecimal对象
-
-
BigDecimal常用API
-
方法名 说明 public BigDecimal add(BigDecimal b) 加法 public BigDecimal subtract(BigDecimal b) 减法 public BigDecimal multiply(BigDecimal b) 乘法 public BigDecimal divide(BigDecimal b) 除法 public BigDecimal divide(另一个BigDecimal对象,精确几位,舍入模式) 除法
-
-