Day03多态——常用API
Day03多态——常用API
面向对象三大特征之三:多态
什么是多态?
同类型的对象,执行同一个行为,会表现出不同的行为特征
多态的常见形式
父类类型 对象名称 = new 子类构造器
接口 对象名称 = new 实现类构造器
多态中成员访问特点:
-
方法调用:编译看左边,运行看右边
-
变量调用:编译看左边,运行也看左边(多态侧重行为多态)
多态的前提:
有继承/实现关系;有父类引用指向子类对象;有方法重写
优势:
在多态形势下,右边对象可以实现解耦合,便于扩展和维护
Animal a = new Dog();
a.run; //后续业务行为随对象而变,后续代码无需修改
定义方法的时候,使用父类型作为参数,该方法就可以接收这父类的一切子类对象,体现出堕胎的扩展性和遍历
多态下会产生的一个问题:
多态下不能使用子类的独有功能
自动类型转换(从子到父):子类对象赋值给父类类型的变量指向。
强制类型转换:
此时必须进行强制类型转换: 子类 对象变量= ( 子类) 父类类型的变量
作用: 可以解决多态下的劣势, 可以实现调用子类独有的功能。
注意: 如果转型后的类型和对象真实类型不是同一种类型, 那么在转换的时候就会出现CIassCastException
AnimaI t = new Tortoise();
Dog d = (Dog)t; / / 出现异常CIassCastException
Java 建议强转转换前使用instanceof 判断当前对象的真实类型, 再进行强制转换
变量名lnstanceof 真实类型
判断关键字左边的变量指向的对象的真实类型, 是否是右边的类型或者是其子类类型, 是则返回true, 反之。
强制类型转换能解决什么问题,需要注意什么
-
可以转换成真正的子类类型,从而调用子类独有功能
-
有继承/实现的两个类型就可以进行强制转换,编译无问题。
-
运行时,如果发现强制类型转换后的类型不是对象真实类型则报错
-
ClassCastException
类
内部类
-
内部类就是定义在一个类里面的类, 里面的类可以理解成( 寄生) / 外部类可以理解成( 宿主) 。
public class Peop1e{
//内部类
public class Heart{
}
}
内部类的使用场景、作用
-
当一个事物的内部, 还有一个部分需要一个完整的结构进行描述, 而这个内部的完整的结构又只为外部事物提供服务, 那么整个内部的完整结构可以选择使用内部类来设计。
-
内部类通常可以方便访问外部类的成员, 包括私有的成员
-
内部类提供了更好的封装性, 内部类本身就可以用private protectecd 等修饰, 封装性可以做更多控制。
内部类的分类
静态内部类(了解)
-
有static修饰,属于外部类本身
-
特点与普通类完全一眼给,类的成分它都有,知识位置在别人里面
-
创建对象的格式
-
如果一个类中包含了一个完整的成分,如汽车中的发动机类
外部类名.内部类名 对象名 = new 外部类名.内部类构造器
范例:Outer.Inner in = new Outer.Inner();
public class Outer{
//静态成员内部类
public static class Inner{
}
}
静态内部类的访问拓展:
//1 、静态内部类中是否可以直接访问外部类的静态成员?
. 可以, 外部类的静态成员只有一份可以被共享访问。
//2 、静态内部类中是否可以直接访问外部类的实例成员?
. 不可以的, 外部类的实例成员必须用外部类对象访问。
成员内部类(非静态内部类)(了解)
-
无static修饰,属于外部类的对象
-
JDK16之前,成员内部类中不能定义静态成员,JDK16开始也可以定义静态成员了
-
可以直接访问外部类的静态成员,实例方法中可以直接访问外部类的实例成员
public class Outer{
//成员内部类
public class Inner{
}
}
-
创建对象的格式
外部类名.内部类名 对象名 = new 外部类名.内部类构造器
范例:Outer.Inner in = new Outer().new Inner();
成员内部类访问拓展:
//1 、成员内部类中是否可以直接访问外部类的静态成员?
. 可以, 外部类的静态成员只有一份可以被共享访问。
//2 、成员内部类的实例方法中是否可以直接访问外部类的实例成员?
. 可以的, 因为必须先有外部类对象, 才能有成员内部类对象, 所以可以直接访问外部类对象的实例成员。
成员内部类-面试题
classs People{
private int heartbeat = 150;
public class Heart{
private int heartbeat = 110;
public void show(){
int heartbeat = 78;
System.out.println(heartbeat);//78
System.out.println();//110
System.out.println(People.this heartbeat);//150
}
}
//注意:在成员内部类中访问所在外部类对象,格式:外部类名.this.xxx
局部内部类(了解)
-
局部内部类放在方法、代码块、构造器等执行体中;
-
局部内部类的类文件名为:外部类$N内部类.class;
匿名内部类(重点)
本质上是一个没有名字的局部内部类, 定义在方法中、代码块中、等。
作用: 方便创建子类对象, 最终目的为了简化代码编写。
格式:
new 类丨抽象类名| 或者接口名(){
重写方法;
}
Employee a = new Employee() {
public void work() {
}
}
a.work();
特点总结:
-
匿名内部类是一个没有名字的内部类;
-
匿名内部类写出来就会产生一个匿名内部类的对象;
-
匿名内部类的对象类型相当于是当前new的哪个的类型的子类类型;
匿名内部类在开发中的使用形式了解:(对象回调)
匿名内部类可以作为方法的实际参数进行传输
go(new Swimming() {
@Override
public void swim() {
System.out.println("老师快乐的自由泳🏊");
}
});
匿名内部类在开发中的真实使用场景演示:
public class Test2 {
public static void main(String[] args) {
//1.创建窗口
JFrame win = new JFrame("登录界面");
JPanel panel = new JPanel();
win.add(panel);
//2.创建一个按钮对象
JButton btn = new JButton("登录");
//注意:讲解匿名内部类的使用
/*
btn.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(win,"click");
}
});
*/
btn.addActionListener(e -> JOptionPane.showMessageDialog(win,"click"));
//3.把按钮对象添加到窗口上展示
panel.add(btn);
//4.展示窗口
win.setSize(400,300);
win.setLocationRelativeTo(null);
win.setVisible(true);
}
}
开发中不需要我们去主动定义匿名内部类,而是别人需要我们或者我们可以写的时候才会使用,匿名内部类的代码可以实现代码进一步的简化
常用API
Object类的作用:
一个类要么默认继承了Object 类, 要么间接继承了Object 类, Object 类是Java 中的祖宗类
Object 类的方法是一切子类都可以直接使用的, 所以我们要学习Object 类的方法。
Object 类的常用方法:
| 方法名 | 说明 |
|---|---|
| public String toString() | 默认是返回当前对象在堆内存中的地址信息: 类的全限名@内存地址 |
| public boolean equals(Object o) | 默认是比较当前对象与另一个对象的地址是否相同/ 相同返回true, 不同返回false |
Object 的toString方法:
问题引出:
. 开发中直接输出对象, 默认输出对象的地址其实是毫无意义的。
. 开发中输出对象变量, 更多的时候是希望看到对象的内容数据而不是对象的地址佇审
toString 存在的意义
. 父类tostring() 方法存在的意义就是为了被子类重写, 以便返回对象的内容信息, 而不是地址信息!
toString方法的作用:
-
默认是打印当前对象的地址
-
让子类重写,以便返回子类对象的内容
Object 的equals方法存在的意义:
父类equals方法存在的意义就是为了被子类重写,以便子类自己来定制比较规则
equals方法的作用:
-
默认是与另一个对象比较地址是否一样
-
让子类重写,以便比较两个子类对象的内容是否相同
objects概述:

objects常见方法:
源码分析:
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
//对象进行内容比较的时候建议使用什么?
建议使用objects提供的equals方法
比较的结果都是一样的,但是要更加安全
| 方法名 | 说明 |
|---|---|
| public static boolean equals(Object a, Object b) | 比较两个对象的,底层会下进行非空判断,从而可以避免空指针异常。再进行equals比较 |
| public static boolean isNull(Object obj) | 判断变量是否为null,为null返回true,反之返回false |
StringBuilder概述:
.StringBuilder是一个可变的字符串类, 我们可以把它看成是一个对象容器。
. 作用: 提高字符串的操作效率, 如拼接、修改等。
StringBuilder 构造器
| 名称 | 说明 |
|---|---|
| public StringBuiIder() | 创建一个空白的可变的字符串对象, 不包含任何内容 |
| public StringBuiIder(String str) | 创建一个指定字符串内容的可变字符串对象 |
StringBuilder常用方法:
| 方法名称 | 说明 |
|---|---|
| public StringBuilder append( 任意类型) | 添加数据并返回StringBuiIder 对象本身 |
| public StringBuiIder reverse() | 将对象的内容反转 |
| public int length() | 返回对象内容长度 |
| public String toString() | 通过toString() 就可以实现把StringBuilder 转换为String |
String类拼接字符串原理图

StringBuilder提高效率原理图

为什么拼接、反转字符串建议使用StringBuilder:
. string : 内容是不可变的、拼接字符串性能差。
. StringBuilder : 内容是可变的、拼接字符串性能好、代码优雅。
. 定义字符串使用string
. 拼接、修改等操作字符串使用StringBuiIder
Math类
-
包含执行基本数字运算的方法, Math 类没有提供公开的构造器。
-
如何使用类中的成员呢? 看类的成员是否都是静态的, 如果是, 通过类名就可以直接调用
Math 类的常用方法
| 方法名 | 说明 |
|---|---|
| public static int abs(int a) | 获取参数绝对值 |
| public static double ceil(double a) | 向上取整 |
| public static 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) | 返回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 currentTimeMils() | 返回当前系统的时间毫秒值形式 |
| public static void arraycopy( 数据源数组, 起始索引, 目的地数组, 起始索引, 拷贝个数) | 数组拷贝 |

BigDecimal作用:


浙公网安备 33010602011771号