接口的定义和实现
接口的定义
接口是一种抽象类型,它定义了一组抽象方法,但没有具体的实现。接口使用interface
关键字进行定义,可以包含常量和抽象方法。
public interface Shape {
double calculateArea();
double calculatePerimeter();
}
接口与类相似点:
- 一个接口可以有多个方法。
- 接口文件保存在 .java 结尾的文件中,文件名使用接口名。
- 接口的字节码文件保存在 .class 结尾的文件中。
- 接口相应的字节码文件必须在与包名称相匹配的目录结构中。
接口与类的区别:
-
接口不能用于实例化对象。
- 接口没有构造方法。
- 接口中所有的方法必须是抽象方法,Java 8 之后 接口中可以使用 default 关键字修饰的非抽象方法。
- 接口不能包含成员变量,除了 static 和 final 变量。
- 接口不是被类继承了,而是要被类实现。
- 接口支持多继承。
接口的实现
接口的实现是指一个类实现了某个接口,并提供了接口中定义的抽象方法的具体实现。使用implements
关键字来实现接口。
// 定义接口
public interface Shape {
// 计算面积的抽象方法
double calculateArea();
// 计算周长的抽象方法
double calculatePerimeter();
}
// 实现接口的类
public class Circle implements Shape {
private double radius; // 圆的半径
// 构造方法
public Circle(double radius) {
this.radius = radius;
}
// 实现计算面积的方法
@Override
public double calculateArea() {
return Math.PI * radius * radius; // 计算圆的面积
}
// 实现计算周长的方法
@Override
public double calculatePerimeter() {
return 2 * Math.PI * radius; // 计算圆的周长
}
}
N种内部类
在Java编程中,内部类是一种嵌套在其他类中的类,它可以访问外部类的成员变量和方法。Java中有多种类型的内部类,包括成员内部类、静态内部类、局部内部类和匿名内部类。在本篇博客中,我们将介绍这几种内部类的定义和用法。
成员内部类
成员内部类是定义在另一个类中的类,它可以访问外部类的成员变量和方法。成员内部类的定义方式如下:
public class Outer {
private int outerVar;
public class Inner {
public void innerMethod() {
System.out.println("Accessing outerVar from inner class: " + outerVar);
}
}
}
在上面的例子中,Inner
类是Outer
类的成员内部类,可以直接访问Outer
类的outerVar
变量。
静态内部类
静态内部类是使用static
关键字修饰的内部类,它不依赖于外部类的实例而存在。静态内部类的定义方式如下:
public class Outer {
private static int outerVar;
public static class StaticInner {
public void innerMethod() {
System.out.println("Accessing outerVar from static inner class: " + outerVar);
}
}
}
在上面的例子中,LocalInner
类是outerMethod
方法的局部内部类,只能在outerMethod
方法内部使用。
匿名内部类
匿名内部类是一种没有类名的内部类,通常用于创建只需一次使用的类对象。匿名内部类的定义方式如下:
public class Outer {
public void anonymousInner() {
// 创建匿名内部类实现Runnable接口
Runnable r = new Runnable() {
@Override
public void run() {
System.out.println("Inside anonymous inner class");
}
};
// 创建线程并启动
Thread t = new Thread(r);
t.start();
}
}
在上面的例子中,我们使用匿名内部类实现了Runnable
接口,并在run
方法中输出一条信息。
异常
什么是异常:
异常(Exception):运行中非正常流程的事情
错误(ERROR):不是异常,是脱离控制的问题,通常是灾难性的致命错误
异常举例:
java.lang.StackOverflowError 栈堆异常
public class Demo01 {
public static void main(String[] args) {
new Demo01().a();
}
public void a(){
b();
}
public void b(){
a();
}
}
java.lang.ArithmeticException: / by zero 算数运算异常
public class Demo02 {
public static void main(String[] args) {
System.out.println(11/0);
}
}
Error:
Error类对象由Java虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关
Java虚拟机运行错误(Virtual MachineError),当JVM不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError。这些异常发生时,JVM一般会选择进程终止。
Exception:
一般是由于程序逻辑错误引起的,在程序中应尽可能地去处理这些异常。
异常处理
捕获异常
在Java中,我们可以使用try-catch
语句来捕获异常。try
块用于包含可能抛出异常的代码,而catch
块用于捕获并处理异常。下面是一个简单的例子:
public class ExceptionHandling {
public static void main(String[] args) {
try {
int result = 10 / 0; // 除以零会抛出ArithmeticException
} catch (ArithmeticException e) {
System.out.println("Caught an arithmetic exception: " + e.getMessage());
}
}
}
在上面的例子中,我们使用try-catch
语句捕获了除以零可能抛出的ArithmeticException
异常,并在catch
块中处理了该异常。
抛出异常
除了捕获异常,我们还可以在程序中主动抛出异常。在Java中,可以使用throw
关键字抛出异常。下面是一个简单的例子:
public class ExceptionHandling {
public static void main(String[] args) {
try {
int result = divide(10, 0);
} catch (ArithmeticException e) {
System.out.println("Caught an arithmetic exception: " + e.getMessage());
}
}
public static int divide(int num1, int num2) {
if (num2 == 0) {
throw new ArithmeticException("Division by zero");
}
return num1 / num2;
}
}
在上面的例子中,我们定义了一个divide
方法,如果除数为零,则使用throw
关键字抛出ArithmeticException
异常。
除了try-catch
语句和throw
关键字,Java还提供了finally
块用于执行无论是否发生异常都需要执行的代码,以及throws
关键字用于声明方法可能抛出的异常。
自定义异常:
- 创建自定义异常类
- 在方法中通过throw关键字抛出异常对象
- 如果在抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常
- 在出现异常方法的调用者中捕获并处理异常
//定义全局异常捕获:
public class GlobalException {
@ExceptionHandler(ServiceException.class)
@ResponseBody
public Result serviceExcepiton(ServiceException e){
return Result.error(e.getCode(), e.getMessage());
}
}
//自定义异常捕获:
public class ServiceException extends RuntimeException{
private String code;
public ServiceException(String msg){
super(msg);
this.code = "500";
}
public ServiceException(String code, String msg){
super(msg);
this.code = code;
}
}