1.3 接口的成员特点
- 成员变量
- 只能是常量
- 默认修饰符:public static final
- 构造方法
- 接口没有构造方法,因为接口主要是对行为进行抽象的,是没有具体存在的
- 一个类如果没有父类,默认继承自
Object类
- 成员万法
- 只能是抽象方法
- 默认修饰符:
public abstract
(JDK8
和JDK9
中有一些新特性)
1.4 类和接口的关系
- 类和类的关系
- 继承关系,只能单继承,但是可以多层继承
- 类和接口的关系
- 实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
- 接口和接口的关系
- 继承关系,可以单继承,也可以多继承
- 在这里,我们再次强调抽象类是对事物的抽象,而接口是对行为的抽象
形参和返回值
1.1类名作为形参和返回值
- 方法的形参是类名,其实需要的是该类的对象
- 方法的返回值是类名,其实返回的是该类的对象
1.2抽象类名作为形参和返回值
- 方法的形参是抽象类名,其实需要的是该抽象类的子类对象
- 方法的返回值是抽象类名,其实返回的是该抽象类的子类对象
内部类
1.1内部类概述
内部类:就是在一个类中定义一个类。
举例:在一个类A的内部定义一个类B,类B就被称为内部类
内部类的定义格式
- 格式:
public class 类名{
修饰符 class 类名{
}
}
- 范例:
public class Outer {
public class Inner {
}
}
- 内部类的访问特点
- 内部类可以直接访问外部类的成员,包括私有
- 外部类要访问内部类的成员,必须创建对象
public class Outer {
private int num = 10;
public class Innner {
public void show (){
System.out.println(num);
}
}
public void metchod() {
// show();无法直接访问内部类的成员方法
Innner i = new Innner();
i.show();//只能通过新建对象访问
}
}
1.2 成员内部类
按照内部类在类中定义的位置不同,可以分为如下两种形式
- 在类的成员位置:成员内部类
- 在类的局部位置:局部内部类
成员内部类,外界如何创建对象使用呢?
- 格式:
外部类名.内部类名 对象名 =new 外部类对象.内部类对象;
- 范例:
Outer.Inner oi = new Outer().new Inner();
public class InnerDemo {
public static void main(String[] args) {
Outer.Inner oi = new Outer().new Inner();//调用方法
oi.show();
}
}
1.3 局部内部类
局部内部类是在方法中定义的类,所以外界是无法直接使用,需要在方法内部创建对象并使用
该类可以直接访问外部类的成员,也可以访问方法内的局部变量
1.4 匿名内部类
前提:存在一个类或者接口,这里的类可以是具体类也可以是抽象类
- 格式:
new 类名或者接口名 () {
重写方法;
};
- 范例
new Inter() {
public void show() {
@Override
......
};
};
本质:是一个继承了该类或者实现了该接口的子类匿名对象
范例:
有一个接口Jumpping
:
package com.nimingneibulei;
public interface Jumpping {
void jump();
}
有一个操作类JumppingOperator
:
package com.nimingneibulei;
public class JumppingOperator {
public void method(Jumpping j) {
j.jump();
}
}
在测试类JumppingDemo
中:
package com.nimingneibulei;
public class JumppingDemo {
public static void main(String[] args) {
JumppingOperator jo = new JumppingOperator();
jo.method(new Jumpping() {
@Override
public void jump() {
System.out.println("猫可以跳高了");
}
});
jo.method(new Jumpping() {
@Override
public void jump() {
System.out.println("狗可以跳高了");
}
});
}
}
//可以不用另外再新建cat类和dog类,使代码更简洁
常用API
1. Math
1.1 Math 类概述
- Math包含执行基本数字运算的方法(通过查看帮助文档)
没有构造方法,如何使用类中的成员呢?
- 看类的成员是否都是静态的,如果是,通过类名就可以直接调用
1.2 Math类的常用方法
方法名 | 说明 |
public static int abs(int a) | 返回参数的绝对值 |
public static double ceil(double a) | 返回大于或等于参数的最小double值,等于一个整数 |
public static double floor(double a) | 返回小于或等于参数的最大double值,等于一个整数 |
public static int round(float a) | 按照四舍五入返回最接近参数的int |
public static int max(int a,int b) | 返回两个int值中的较大值 |
public static int min(int a,int b) | 返回两个int值中的较小值 |
public static double pow(double a,double b) | 返回a的b次幂的值 |
public static double random() | 返回值为double的正值,[0.0,1.0) |
2. System
2.1 System类的常用方法
方法名 | 说明 |
| 终止当前运行的Java虚拟机, |
| 返回当前时间(以毫秒为单位) |
3. Object
3.1 Object类的概述
Object是类层次结构的根,每个类都可以将Object作为超类。
所有类都直接或者间接的继承自该类
构造方法: public Object()
回想面向对象中,为什么说子类的构造方法默认访问的是父类的无参构造方法?
因为它们的顶级父类只有无参构造方法
3.2 Object类的toString()方法
public String toString()
当s是一个对象时,执行System.out.println(s)
会自动执行s.toString()
方法,当没有重写toString()
方法时,会访问父类(直至根父类Object类
)中的toString()
方法,即输出对象的包名@哈希值
- 建议所有子类重写此方法
- 如何重写呢?IDEA中按
ALT
+inSert
可自动生成toString()
方法
3.3 Object类的equals()方法
public boolean equals(Object obj)
比较对象是否相等。默认比较地址,重写可以比较内容,自动生成
4. Arrays
4.1 冒泡排序
- 如果有n个数据进行排序,总共需要比较n-1次
- 每一次比较完毕,下一次的比较就会少一个数据参与
代码:
import java.util.Arrays;
public class demo {
public static void main(String[] args) {
int[] arr = {3, 2, 5, 6, 4, 1, 0};
System.out.println("排序前:" + Arrays.toString(arr));
for (int x = 0; x < arr.length - 1; x++) {
for (int i = 0; i < arr.length - 1 - x; i++) {
if (arr[i] > arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
}
System.out.println("排序后:" + Arrays.toString(arr));
}
}
4.2 Arrays类的概述和常用方法
Arrays类包含用于操作数组的各种方法
方法名 | 说明 |
| 返回指定数组的内容的字符串表示形式 |
| 按照数字顺序排列指定的数组 |
- 构造方法用private修饰(防止用户创建对象)
- 成员用public static 修饰(为了使用类名访问成员方法)
5. 基本类型包装类
5.1基本类型包装类概述
将基本数据类型封装成对象的好处在于可以在对象中定义更多的功能方法操作该数据
常用的操作之一:用于基本数据类型与字符串之间的转换
基本数据类型 | 包装类 |
byte | Byte |
short | Short |
int | lnteger |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
5.2 Integer类的概述和使用
Integer:包装一个对象中的原始类型int的值
方法名 | 说明 |
public Integer(int value) | 根据int 值创建Integer 对象**(过时)** |
public Integer(String s) | 根据String值创建Integer 对象**(过时)** |
public static Integer valueOf(int i) | 返回表示指定的int值的Integer 实例 |
public static Integer valueOf(String s) | 返回一个保存指定值的Integer 对象String |
代码:
public class demo {
public static void main(String[] args) {
Integer i1 = new Integer(100);//已过时
System.out.println(i1);//100
// Integer i2 = new Integer("abc");//错误:NumberFormatException
Integer i2 = new Integer("100");//已过时
System.out.println(i2);//100
Integer i3 = Integer.valueOf(100);
System.out.println(i3);//100
// Integer i4 = Integer.valueOf("abc");//错误:NumberFormatException
Integer i4 = Integer.valueOf("100");
System.out.println(i4);//100
}
}
5.3 int和String的相互转换
基本类型包装类的最常见操作就是:用于基本类型和字符串之间的相互转换
- int转换为String
//方式1
String s1 = "" + 100;
System.out.println(s1);
//方式2
String s2 = String.valueOf(100);
System.out.println(s2);
- String转换为int
//方式1
//String---Integer---int
String s1 = "100";
Integer i1 = Integer.valueOf(s1);
int x1 = i1.intValue();
System.out.println(x1);
//方式2
//String---int
String s2 = "100";
int x2 = Integer.parseInt(s2);
System.out.println(x2);
- 将非数字的String转换为int会报错
NumberFormatException
5.4 自动装箱和拆箱
- 装箱:把基本数据类型转换为对应的包装类类型
- 拆箱:把包装类类型转换为对应的基本数据类型
Integer in = Integer.valueOf(100);//装箱
Integer in2 = 100;//自动装箱,JDK5以后会自动执行Integer.valueOf(100);
int i = in.intValue();//拆箱
int i2 = in;//自动拆箱
in += 2;//自动拆箱+自动装箱
不可对null
进行拆箱和装箱,会抛出空指针异常NullPointerException
Integer iii = null;
iii += 300;//NullPointerException
int iiii = Integer.parseInt(null);//NullPointerException
- 开发中对于引用类型建议先进行判空再进行操作
注意:在使用包装类类型的时候,如果做操作,最好先判断是否为null
我们推荐的是,只要是对象,在使用前就必须进行不为null的判断
6. 日期类
6.1 Date类概述和构造方法
- Date类重写了toString方法
6.2 Date类的常用方法
方法名 | 说明 |
| 获取的是日期对象从1970年1月1日00:00:00到现在的毫秒值 |
| 设置时间,给的是毫秒值 |
6.3 SimpleDateFormat 类概述
SimpleDateFomat
是一个具体的类,用于以区域设置敏感的方式格式化和解析日期。我们重点学习日期格式化和解析
日期和时间格式由日期和时间模式字符串指定,在日期和时间模式字符串中,从‘A’到‘Z’以及从‘a’到‘Z’引号的字母被解释为表示日期或时间字符串的组件的模式字母
常用的模式字母及对应关系如下:
- y 年
- M 月
- d 日
- H 时
- m 分
- s 秒
6.4 SimpleDateFormat的构造方法
方法名 | 说明 |
| 构造一个SimpleDateFormat,使用默认模式和日期格式 |
| 构造一个SimpleDateFormat使用给定的模式和默认的日期格式 |
6.5 SimpleDateFormat 格式化和解析日期
1.格式化(从Date到 String)public final String format(Date date)
:将日期格式化成日期/时间字符串
2.解析(从String到 Date )public Date parse(String source)
:从给定字符串的开始解析文本以生成日期
示例:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class demo {
public static void main(String[] args) throws ParseException {
//格式化:Date到String
Date d = new Date();
// SimpleDateFormat sdf = new SimpleDateFormat();//默认格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
String s = sdf.format(d);
System.out.println(s);
System.out.println("--------");
//从String到Date
String ss= "2022-04-12 11:11:11";
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date dd = sdf2.parse(ss);//使用此方法需要在类中添加throws ParseException(抛出异常)
System.out.println(dd);
}
}
输出:
2022年04月12日 04:33:55
--------
Tue Apr 12 11:11:11 CST 2022
当转换格式和给出的格式不一致时会报解析异常(ParseException
)
6.6 Calendar类概述
Calendar为某一时刻和一组日历字段之间的转换提供了一些方法,并为操作日历字段提供了一些方法
Calerndar提供了一个类方法gellrnslance用于获取Calendar对象,其日历字段已使用当前日期和时间初始化:Calendar rightNow = Calendar.getlnstance();
6.7 Calendar的常用方法
方法名 | 说明 |
public int get(int field) | 返回给定日历字段的值 |
public abstract void add(int field, int amount) | 根据日历的规则,将指定的时间量添加或减去给定的日历字段 |
public final void set(int year,int month,int date) | 设置当前日历的年月日 |
import java.util.Calendar;
public class demo {
public static void main(String[] args) {
//获取日历对象
Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
int date = c.get(Calendar.DATE);
System.out.println(year + "年" + month + "月" + date + "日");//2022年3月12日
}
}
计算三年前的今天:
package com.demo;
import java.util.Calendar;
public class demo {
public static void main(String[] args) {
//获取日历对象
Calendar c = Calendar.getInstance();
c.add(Calendar.YEAR,-3);//年减三
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
int date = c.get(Calendar.DATE);
System.out.println(year + "年" + month + "月" + date + "日");//2019年3月12日
}
}
注意:月份是从0开始的
异常
1.1 异常概述
异常:就是程序出现了不正常的情况
- 异常体系:
Throwable
Error
Exception
RuntimeException
非RuntimeException
Error:严重问题,不需要处理
Exception:称为异常类,它表示程序本身可以处理的问题
1.2 JVM的默认处理方案
如果程序出现了问题,我们没有做任何处理,最终JⅣM会做默认的处理
- 把异常的名称,异常原因及异常出现的位置等信息输出在了控制台
- 程序停止执行
1.3异常处理
如果程序出现了问题,我们需要自己来处理,有两种方案:
- try … catch …
- throws
1.4异常处理之try…catch…
- 格式:
try {
可能出现异常的代码;
} catch(异常类名 变量名) {
异常的处理代码;
}
- 执行流程:
程序从try里面的代码开始执行
出现异常,会自动生成一个异常类对象,该异常对象将被提交给Java运行时系统
当Java运行时系统接收到异常对象时,会到catch中去找匹配的异常类,找到后进行异常的处理执行完毕之后,程序还可以继续往下执行 - 示例:
public class demo {
public static void main(String[] args) {
int[] array = {1, 2, 3};
try {
System.out.println(array[3]);//异常时jvm虚拟机会自动new ArrayIndexOutOfBoundsException("xxx")
} catch (ArrayIndexOutOfBoundsException m) {//与前面创建的异常类进行对比
m.printStackTrace();//打印异常信息
}
}
}
1.5 Throwable的成员方法
方法名 | 说明 |
| 返回此 throwable的详细消息字符串 |
| 返回此可抛出的简短描述 |
| 把异常的错误信息输出在控制台 |
1.6编译时异常和运行时异常的区别
Java中的异常被分为两大类:编译时异常和运行时异常,也被称为受检异常和非受检异常
- 编译时异常:必须显示处理,否则程序就会发生错误,无法通过编译
- 运行时异常:无需显示处理,也可以和编译时异常一样处理(例如数据下标访问越界)
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class demo {
public static void main(String[] args) {
method();
}
//编译时异常
public static void method() {
String s ="2022-04-14";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date d = null;
try {
d = sdf.parse(s);
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println(d);
}
}
1.7异常处理之throws
虽然我们通过try …catch…可以对异常进行处理,但是并不是所有的情况我们都有权限进行异常的处理
也就是说,有些时候可能出现的异常是我们处理不了的,这个时候该怎么办呢?
针对这种情况,Java提供了throws的处理方案
- 格式:
throws 异常类名;
注意:这个格式是跟在方法的括号后面的
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class demo {
public static void main(String[] args) {
try {
method();
} catch (ParseException e) {
e.printStackTrace();
}
}
//throws只是抛出异常,还需要在其他地方使用try...catch...处理
public static void method() throws ParseException {
String s = "2022-04-14";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date d = sdf.parse(s);
System.out.println(d);
}
}
1.8自定义异常
格式:
public class异常类名extends Exception {
无参构造
带参构造
}
范例:
public class ScoreException extends Exception {
public ScoreException() {
}
public ScoreException(String message) {
super(message);
}
}
public void checkScore(int score) throws ScoreException {
if (score<0||score>100) {
// throw new ScoreException();//无参构造
throw new ScoreException("你输入的分数有误");//带参构造
} else {
System.out.println("分数正常");
}
}
1.9 throws和throw的区别
throws | throw |
用在方法声明后面,跟的是异常类名 | 用在方法体内,跟的是异常对象名 |
表示抛出异常,由该方法的调用者来处理 | 表示抛出异常,由方法体内的语句处理 |
表示出现异常的一种可能性,并不一定会发生这些异常 | 执行throw一定抛出了某种异常 |