JavaSE进阶——Day03 多态、内部类、时间日期格式类
JavaSE进阶——Day03 该篇主要讲解Java中的多态、内部类、时间日期格式类
学习目标
多态
多态的前提
多态的成员访问特点
多态的优缺点
多态的转型
内部类
成员内部类
匿名内部类
常用API
Object类
Objects类
Date类
SimpleDateFormat类
LocalDateTime类
Period & Duration
Math类 & System类
回顾
工具类的书写规则:
- 工具类,修饰为final(不让继承)
- 工具类的构造方法,设置为private(不让其他类创建对象)
- 工具类中提供:静态方法(通过类名访问)
static关键字
解决程序中什么问题?
1
2静态变量:共享数据
静态方法:工具类中方法的编写怎么使用
1
2
3
4
5
6
7
8
9
10public class 类{
static 类型 变量名;
public static 返回值类型 方法名(参数, ..){
}
}
类名.静态变量名=100;
类名.静态方法名();细节:
- 静态内容是随着类的加载,存放在方法区的静态区域下(仅有一份)【早于对象创建】
- 静态方法中不能使用this关键字
- 静态方法只能访问静态内容(静态变量、静态方法)
final关键字
- final修饰的类, 不能继承
- final修饰的方法, 不能被重写
- final修饰的变量, 初始化值后不能修改其值(变为常量)
代码块:
1 | static{ |
接口:
接口的作用:制定规则
接口的使用
接口定义(制定规则)
1
2
3
4
5
6public interfce 接口名{
//常量
public static final String 常量名 = 值;
//抽象方法(制定规则)
public abstract 返回值类型 方法名(参数, ...);
}接口实现(按照规则实现代码)
1
2
3public 接口实现类 implements 接口名{
//重写接口中的抽象方法
}
问题:在继承时,子类可能把父类的构造方法继承了吗?
答案:不可以。
枚举:
解决什么问题?
1
当程序中的某个数据有固定在一定范围的取值时,为保障程序中数据的有效性,可以使用:枚举
使用方式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22public enum 枚举名{
固定选项值1,固定选项值2,...;
}
枚举名.选项值;
public enum Sex{
BOY,GIRL;
}
public class Student{
private Sex sex;
}
Student stu = new Student( Sex.BOY )
多态
什么是多态?
1 | 多态:多种形态 |
多态解决程序中的什么问题?
1 | 1、提高代码的复用性 |
多态的使用
1 | //多态的代码体现格式: |
多态在使用时的注意细节
- 多态中:父类和子类拥有一模一样的成员变量时:
- 编译时:以父类型中的成员变量为主
- 运行时:使用父类中的成员变量
- 多态中:父类和子类拥有一模一样的成员方法时:
- 编译时:以父类中的成员方法为主(检查父类中有没有这个成员方法,没有:报错)
- 运行时:以子类中的成员方法为主(调用子类对象中重写后的成员方法)
多态转型
向上转型(自动类型提升)
1
2
3
4//基础班: int a =10; long num = a;
//多态:
父类型 父引用 = new 子类(); //子类型变为:父类型 (弊端:父引用不能使用子类特有成员)向下转型(强制类型转换)
1
2
3
4
5
6//解决的问题: 父引用不能使用子类中特有成员
//基础班: long a =100L; int b = (int) a;
//多态的向下转型:
子类 对象 = (子类) 父引用;
多态代码的书写:
创建对象
1
2//父类型 父引用 = new 子类()
Father f = new Son();作为参数
1
2
3
4public void method( Father f )
{
f.方法()
}作为返回值
1
2
3
4
5public Animal getInstance()
{
//返回:子类对象
return new Cat();
}
内部类:
1 | public class HelloWorld{ |
问题:如何访问某个类中的成员变量or成员方法?
答案:创建类的对象,通过”对象名.成员”的方式访问
匿名内部类:
解决程序中什么问题?
1
简化程序中代码的书写
怎么使用?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28//语法格式:
new 类名/接口(){
//重写方法
}
//示例:
public class Father{
public String sayHello(String name){
return "早上好, "+ name;
}
}
//此时:程序的需求发生改变,要求sayHello方法的返回值为"你好,名字"
public class Son extends Father{
//重写sayHello方法
public String sayHello(String name){
return "你好, "+name;
}
}
//以下代码使用匿名内部的方式(其实本质就是一个子类对象)
new Father(){
//把父类中的方法重写
public String sayHello(String name){
return "晚上好,"+name;
}
}
工具类:为解决某些特定问题,特意编写的公共类(程序员都可以使用)
- JDK(java开发工具包) = JRE + 核心类库
- 核心类库: jdk提供一些现成的功能,这些功能封装在不同的类中
- JDK就提供了一些工具类:Math、Arrays
- Arrays工具类:针对数组,提供了一系列现成的功能(例:排序)
总结
多态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29//多态可以解决程序中什么问题?
1、提高程序中代码的复用性
2、提高程序中代码的扩展性
//多态怎么使用?
//1、创建一个对象
父类型 父引入 = new 子类();
//2、作为参数
public void method(父类型 父引用){
父引用.成员方法()
}
//3、作为返回值
public 父类型 getInstance(){
return 子类对象;
}
//多态在使用中的细节
父子类中有相同的成员变量时:编译和运行都以父类型中的成员变量为主
父子类中有相同的成员方法时:编译时检查父类型中的成员方法是否存在
运行时以子类对象中的重写的方法为主
//多态的转型
向上转型: 父类型 父引入 = new 子类(); //弊端:父引用不能访问子类对象中特有成员
向下转型: 子类 对象 = (子类) 父引用; //向下转换后,可以访问子类对象中特有成员
在向下转型时容易发生:ClassCastException 异常
使用:instanceof 避免 ClassCastException异常发生
if(父引用 instanceof 子类类型){
子类 对象 =(子类) 父引用;
}匿名内部类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23//匿名内部类解决什么问题?
简化程序中的代码
//匿名内部类的使用
父类型 父引用 = new 父类/接口(){
//重写父类型中的方法
};
//作为参数
public void show( Flyable fly );
show( new Flyalbe(){
//重写方法
} );
//作为返回值
public Flyable getInstance(){
return new Flyable(){
//重写方法
};
}
在Java继承体系中,有一个顶层父类:Object(鼻祖类)
- 在java语言中,程序员自定义的类或者jdk中存在的类,直接或间接都要继承Object
- 继承了Object类后,就可以使用Object提供的相关方法:
- boolean equals(Object obj)
- boolean: 方法的返回值类型
- Object: 方法传递参数的类型
- 作用:比较两个对象是否相同(比较两个对象的地址值是否相同)
- String toString()
- 作用: 把对象转换为字符串
- boolean equals(Object obj)
比较两个字符串是否相同 :
1 | //方案1: String类中的equals方法 |
日期类型的数据:
1 | public class Emp |
Date类:
归属包:java.util
作用:表示日期时间(精确到毫秒)
使用:
构造方法(创建对象)
1
2public Date()
public Date(long time)常用方法
DateFormat类
1 | //DateFormat类是什么 |
Calendar类:日历类(存储的有日期、时间、日历信息)
- 代替java.util.Date类中的过期方法
1 | //Calendar类的使用: 构造方法、 常用方法 |
Calendar对象中存储的内容:
1 | java.util.GregorianCalendar[ |
获取Calendar对象中存储的数据:
1 | //API方法: public int get(int 字段名) //字段名:YEAR MONTH DAY_OF_MONTH |
给日历对象设置具体的:年月日时分秒……
1 | //获取日历对象中的年 |
给日历对象中的信息,增加或减少
1 | public void add(int 字段 , int 数值) //数值是负数是减少 , 数据是正数表示增加 |