1. 方法覆盖
方法覆盖(overriding)是指子类中定义了与父类中同名、同参数又有不同实现的一种机制。在Java中,方法覆盖有以下规则:
1.1 方法覆盖的前提条件
要想进行方法覆盖,必须满足以下条件:
子类方法的访问权限要高于等于父类方法的访问权限。例如,父类方法为public,则子类方法必须为public或protected。
子类方法的返回类型要与父类方法的返回类型相同或是其子类型。
子类方法必须与父类方法有相同的方法名和方法参数列表。
1.2 方法覆盖的实现
当子类和父类中出现同名、同参数的方法时,子类中的方法会覆盖父类中的方法。发生方法覆盖后,当使用子类对象引用调用该方法时,实际上是调用了子类中的方法。
以下是一个例子:
class Animal {
public void move() {
System.out.println("动物可以移动");
}
}
class Dog extends Animal {
public void move() {
System.out.println("狗可以跑和走");
}
}
public class TestDog {
public static void main(String args[]) {
Animal a = new Animal(); // Animal 对象
Animal b = new Dog(); // Dog 对象
a.move(); // 执行 Animal 类的方法
b.move(); // 执行 Dog 类的方法
}
}
输出结果为:
动物可以移动
狗可以跑和走
在上述例子中,子类Dog继承了父类Animal,并覆盖了父类中的move()方法。当使用Animal对象或Dog对象调用move()方法时,会调用各自类中的方法。
1.3 静态方法不能被覆盖
静态方法属于类,而非对象,因此不能被覆盖。但是,如果在子类中定义了一个与父类中同名、同参数的静态方法,该方法会与父类中的静态方法形成方法重载。
2. 异常处理
异常处理是Java语言的一项重要功能,在Java中,异常处理有以下规则:
2.1 异常分类
Java中的异常分为两类:编译时异常和运行时异常。
编译时异常:这种异常在Java代码编译阶段就可以被捕获到,需要在代码中显式处理它们,若不处理则无法通过编译。比如IOException、ClassNotFoundException等。
运行时异常:这种异常是在代码运行期间抛出的,不需要在代码中显式声明或捕获,可以选择不处理。比如NullPointerException、IndexOutOfBoundsException等。
2.2 异常处理语法
在Java中,使用try、catch、finally语句块来进行异常处理。try块中包含可能抛出异常的代码,catch块用于处理程序运行过程中抛出的异常,finally块包含无论是否抛出异常都需要执行的代码。
下面是一个示例:
public class ExceptionTest {
public static void main(String[] args) {
try {
int a[] = new int[2];
System.out.println("Access element three :" + a[3]); // 抛出异常
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Exception thrown :" + e);
} finally {
System.out.println("Finally block always executed");
}
System.out.println("Out of the block");
}
}
输出结果为:
Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 3
Finally block always executed
Out of the block
在上述例子中,try块抛出了一个ArrayIndexOutOfBoundsException异常,catch块捕获了该异常并进行了相应的处理,finally块中的代码始终会被执行。最后,程序执行完try-catch-finally块后输出"Out of the block"。
2.3 抛出异常
在Java中,可以使用throw关键字抛出一个异常,并用throws关键字声明可能抛出的异常,让调用者知道需要处理哪些异常。
下面是一个示例:
public class ThrowsExample {
public static void main(String[] args) {
try {
testException(0);
} catch (CustomException e) {
System.out.println(e.getMessage());
}
}
public static void testException(int i) throws CustomException {
if (i == 0) {
throw new CustomException("i 等于 0");
}
}
}
class CustomException extends Exception {
public CustomException(String message) {
super(message);
}
}
在上述例子中,testException()方法中当参数i等于0时抛出了一个CustomException异常。main()方法调用testException()时使用了try-catch语句块进行异常处理。CustomException是自定义的异常类,继承了Exception类。
2.4 自定义异常
在Java中,可以通过继承Exception类或RuntimeException类来定义自己的异常类,从而实现自定义异常处理机制。
下面是一个示例:
public class CustomException extends Exception {
public CustomException(String message) {
super(message);
}
}
public class CustomExceptionTest {
public static void validateAge(int age) throws CustomException {
if (age < 18) {
throw new CustomException("年龄不得小于18岁");
} else {
System.out.println("年龄验证通过");
}
}
public static void main(String[] args) {
try {
validateAge(16);
} catch (CustomException e) {
System.out.println("发生异常:" + e.getMessage());
}
}
}
在上述例子中,CustomException继承了Exception类,用于自定义年龄验证失败时抛出的异常。validateAge方法中,当参数age小于18时抛出CustomException异常。main方法调用validateAge时使用了try-catch语句块进行异常处理。
总结
本文介绍了Java中方法覆盖和异常处理的规则和语法。方法覆盖要满足访问权限、返回类型和方法名参数列表等条件,使用子类对象引用调用覆盖的方法时会调用子类中的方法。异常分类分为编译时异常和运行时异常,使用try-catch-finally语句块进行处理。可以使用throw和throws关键字来抛出和声明异常,并通过继承Exception类或RuntimeException类来定义自定义异常。