Java---Chapter 7 (Abstract Class, Interface, Polymorphism, Object, Exception Handling)

insert image description here

an abstract class

Introduction to abstract classes

concept:

An abstract class is a class declared as abstract - it may or may not contain abstract methods, an abstract class cannot be instantiated, but can be subclassed (i.e. can be inherited)

Abstract class definition syntax:

public abstract class 类名{
    
    //定义一个抽象类

}

Abstract method definition syntax:
know to do something, but don't know how to do it

访问修饰符 abstract 返回值类型 方法名(参数列表);

Abstract class application scenarios

Generally speaking, abstract classes are used to describe abstract things.
For example: animals, equipment, geometric figures, etc.

public abstract class Animal {
    
    
    public abstract void eat();
}

public class Panda extends Animal {
    
    

    @Override
    public void eat() {
    
    
        System.out.println("熊猫吃竹叶");
    }
}
public class PersonTest{
    
    
    public static void main(String[] args) {
    
    
        Panda a = new Panda();
        a.eat();
    }
}

If a class inherits from an abstract class, then the class must implement all the abstract methods in the abstract class. Otherwise, the class must define an abstract class.
An abstract class does not necessarily have an abstract method. An abstract method must be an abstract class.

two interface

Interface introduction

In the Java programming language, an interface is similar to a reference type of a class. It can only contain constants, method signatures, default methods, static methods and nested types
Method bodies are only available for default and static methods.
Interfaces cannot be instantiated – they can only be implemented by classes or extended by other interfaces

Interface declarations can contain method signatures, default methods, static methods, and constant definitions .
Methods with implementations are default methods and constant methods

There is no constructor in the interface

grammar:

[public] interface 接口名{
    
    
	[public static final]数据类型 变量名 = 变量的值;
	//接口中定义变量,该变量是静态变量,在定义时必须赋值

	返回值类型 方法名([参数列表]);//定义接口方法
	
	default 返回值类型 方法名([参数列表]){
    
    
	//接口中定义的默认方法,必须在JDK8及以上版本使用
		[return 返回值;]
	}

	static 返回值类型 方法名([参数列表]){
    
    
	//接口中定义的静态方法,必须在JDK8及以上版本使用
		[return 返回值;]
	}

	private 返回值类型 方法名([参数列表]){
    
    
	//接口中定义的私有方法,必须在JDK9及以上版本使用
		[return 返回值;]
	}
}

Example:

public interface Test {
    
    
    public static final int number = 10;
    public abstract void show();
    public default int plus(int a,int b){
    
    
        return a+b;
    }
    public default int multiply(int x,int y){
    
    
        return x*y;
    }
    private String getName(){
    
    
        return "admin";
    }
}

interface inheritance

grammar:

[public] interface 接口名 extends 接口名1,接口名2,....接口名n{
    
    

}

Note: Interfaces can have multiple inheritance, which is the only place in Java where multiple inheritance can be used. The variables contained in the interface are all static constants, and the method signatures contained in the interface are all public abstract methods. The default method and static method in the interface can only be defined in JDK8 and above versions, and the private methods of the interface must be defined in JDK9 and above versions . After the interface is compiled, the desired class file will also be generated

interface implementation

grammar:

访问修饰符 class 类名 implements 接口名1,接口名2,...接口名n{
    
    
}

A class implementing an interface must implement all the methods declared in the interface

If a class implements an interface, it must implement all the abstract methods defined in the interface (including the abstract methods inherited by the interface through the inheritance relationship). This class is called the implementation class or subclass of the interface, and the inheritance relationship Similarly, the relationship between the implementation class and the interface is also an is-a relationship

practise:

The printer has ink cartridge (color) and paper (size) interfaces exposed to the outside. Ink cartridge manufacturers produce black and white ink cartridges and color ink cartridges according to the agreement on the ink cartridge interface, and paper manufacturers produce A2 and A4 paper according to the agreement on the paper interface.

Interface:
Cartridge:

public interface InkBox {
    
    
    String getcolor();
}

paper:

public interface Paper {
    
    
    String getsize();
}

Class:
Monochrome Printer:

public class BlackInkBox implements InkBox{
    
    
    @Override
    public String getcolor() {
    
    
        return "黑白";
    }
}

color printer:

public class ColorInkBox implements InkBox{
    
    
    @Override
    public String getcolor() {
    
    
        return "彩色";
    }
}

A2 paper:

public class A2Paper implements Paper{
    
    
    @Override
    public String getsize() {
    
    
        return "A2";
    }
}

A4 paper:

public class A4Paper implements Paper{
    
    
    @Override
    public String getsize() {
    
    
        return "A4";
    }
}

printer:

public class Printer {
    
    
    private InkBox inkBox;
    private Paper paper;
    public Printer(){
    
    
    }
    public Printer(InkBox inkBox, Paper paper) {
    
    
        this.inkBox = inkBox;
        this.paper = paper;
    }
    public void print(){
    
    
        System.out.printf("打印机使用%s墨盒打印%s纸张上打印\n",inkBox.getcolor(),paper.getsize());
    }
    public InkBox getInkBox() {
    
    
        return inkBox;
    }
    public void setInkBox(InkBox inkBox) {
    
    
        this.inkBox = inkBox;
    }
    public Paper getPaper() {
    
    
        return paper;
    }
    public void setPaper(Paper paper) {
    
    
        this.paper = paper;
    }
}

test:

public class PrinterTest {
    
    
    public static void main(String[] args) {
    
    
        Printer p1 = new Printer();
        p1.setInkBox(new ColorInkBox());
        p1.setPaper(new A4Paper());
        p1.print();

        Printer p2 = new Printer(new BlackInkBox(),new A2Paper());
        p2.print();
    }
}

The difference between three abstract classes and interfaces

  • An abstract class has a constructor, while an interface has no constructor
  • Abstract classes can define member variables, static variables, and static constants, while interfaces can only define public static constants
  • Methods in abstract classes can have protected and default methods, while methods in interfaces are public (except for private methods that can be defined in JDK9)
  • Abstract classes are mainly used to describe abstract things, while interfaces are mainly used to describe conventions and rules
  • Abstract classes can only inherit single inheritance, while interfaces can implement multiple inheritance

Four polymorphism (Polymorphism)

Introduction to polymorphism:

concept:

The dictionary definition of polymorphism is the principle in biology in which an organism or substance can take on many different forms or phases.
This principle can also be applied to object-oriented programming and languages ​​like the Java language.
A subclass can define its own unique behavior, but share some of the same characteristics of the parent class.

From the above description we can get:

  • Inheritance, interface is the concrete embodiment of polymorphism
  • Polymorphism is mainly reflected in categories and ways of doing things
  • Polymorphism is one of the three major characteristics of object-oriented
  • Polymorphism is divided into two categories : compile-time polymorphism (method overloading) and runtime polymorphism

Compile-time polymorphism:
example:
method overloading

Calculate the sum of two random numbers

public class Printer {
    
    
    public long calculate(long a,long b){
    
    
        return a + b;
    }
    public double calculate(double a,double b){
    
    
        return a + b;
    }
}
public class PrinterTest {
    
    
    public static void main(String[] args) {
    
    
        Printer p = new Printer();
        long result1 = p.calculate(1,2);
        double result2 = p.calculate(1.0,2.0);
    }
}

Runtime polymorphism:

The Java Virtual Machine (JVM) calls the appropriate method for the object referenced in each variable. It does not call methods defined by the variable's type . This behavior is called virtual method calling, and it illustrates an aspect of an important polymorphic feature in the Java language

The parent class defines a method

public class Printer {
    
    
    public void show(){
    
    
        System.out.println("Father");
    }
}

Subclasses override this method

public class Person extends Printer{
    
    
    @Override
    public void show() {
    
    
        System.out.println("Child");
    }
}
public class PrinterTest {
    
    
    public static void main(String[] args) {
    
    
        //变量f的类型是Printer
        Printer p = new Person();
        //p调用show()时,不会调用Printer定义的方法
        p.show();
    }
}

Five instanceof operator

instanceof itself is an instance of what it means.
Mainly used in type coercion.
When using type coercion, if it is used incorrectly, an error will be reported at runtime.
The instanceof operator detects the target type of the conversion, and if so, performs a mandatory type conversion , which can ensure the normal operation of the program

grammar:

对象名 instanceof 类名;//表示检测对象是否是指定类型的一个实例,返回值为boolean型

practise:

A shopping mall has televisions, electric fans, air conditioners and other electrical equipment on display. Existing quality inspectors inspect these electrical equipment. If it is a TV, they can play video inspections; if it is an electric fan, they will start the electric fan;

Abstract class of electrical equipment:

public abstract class Device {
    
    
    public abstract void show();
}

TV set:

public class TV extends Device{
    
    
    @Override
    public void show() {
    
    
        System.out.println("这是电视机");
    }
    public void vedio(){
    
    
        System.out.println("播放电视剧");
    }
}

air conditioner:

public class AirCod extends Device{
    
    

    @Override
    public void show() {
    
    
        System.out.println("这是空调");
    }
    public void ice(){
    
    
        System.out.println("制冷");
    }
}

Electric fan:

public class ElectronicFan extends Device{
    
    
    @Override
    public void show() {
    
    
        System.out.println("这是电风扇");
    }
    public void start(){
    
    
        System.out.println("启动电风扇");
    }
}

Quality inspection:

public class Quality {
    
    
    public void test(Device device){
    
    
        device.show();
        if(device instanceof TV){
    
    
            ((TV)device).vedio();
        } else if (device instanceof  AirCod) {
    
    
            ((AirCod)device).ice();
        } else if (device instanceof  ElectronicFan) {
    
    
            ((ElectronicFan)device).start();
        }
    }
}

test:

public class DeviceTest {
    
    
    public static void main(String[] args) {
    
    
        Quality q = new Quality();
        q.test(new TV());
        q.test(new AirCod());
        q.test(new ElectronicFan());
    }
}

Six common methods of Object class

Most of the methods defined in the Object class are native methods (local methods), implemented in **C++**

getClass()

public final Class getClass()

The getClass() method returns a Class object that has methods that can be used to obtain information about the class such as its name (getSimpleName()), its superclass // (getSuperclass()) and the interfaces it implements (getInterfaces() )

package org.device.Device;

public class DeviceTest {
    
    
    public static void main(String[] args) {
    
    
        Quality q = new Quality();
        q.test(new TV());
        q.test(new AirCod());
        q.test(new ElectronicFan());

        TV tv = new TV();
        Class clazz  = tv.getClass();
        String name = clazz.getSimpleName();//获取类名
        System.out.println(name);
        String className = clazz.getName();//获取类的全限定名
        System.out.println(className);

        Class superclass = clazz.getSuperclass();//获取父类的定义信息
        String superName = superclass.getSimpleName();//获取父类的名称
        System.out.println(superName);
        String superClassName = superclass.getName();//获取父类的全限定名
        System.out.println(superClassName);

        String s = "admin";
        Class stringClass  = s.getClass();
        Class[] interfaceClasses = stringClass.getInterfaces();
        for(int i=0;i<interfaceClasses.length;i++){
    
    
            Class interfaceClass  = interfaceClasses[i];
            String interfaceName = interfaceClass.getSimpleName();//获取接口的名称
            System.out.println(interfaceName);
            String interfaceClassName = interfaceClass.getName();//获取接口的全限定名
            System.out.println(interfaceClassName);
        }
    }
}

hashCode()

public int hashCode()

The return value is the hash code of the object, which is the memory address of the object (hexadecimal 0x...)

By definition, if two objects are equal, their hash codes must also be equal.
If you override the equals() method, you change how two objects are equal, and Object's implementation of hashCode() is no longer valid.
Therefore, if you override the equals() method, you must also override the hashCode() method

The hashCode() method in the Object class returns the memory address of the object. Once the hashCode() method is rewritten, the hashCode() method in Object becomes invalid, and the value returned by hashCode() is no longer the memory address

According to the definition, if two objects are equal, the hash code must be equal, otherwise, if the
equals method is rewritten, the hashCode method must be rewritten to meet the above definition conclusion

rewrite hashCode()

    @Override
    public int hashCode(){
    
    
        return name.hashCode() + age;
    }

equals(Object obj)

public boolean equals(Object obj)

The equals() method compares two objects for equality and returns true if they are equal.
The equals() method provided by the Object class uses the identity operator (==) to determine whether two objects are equal.
For primitive data types, this will give correct results .
But for objects , the equals() method provided by Object tests whether the object references are equal, that is, whether the objects being compared are exactly equal

To test whether two objects are exactly equal (contain the same information) in terms of equivalence, the equals() method must be overridden.

public class Student {
    
    
    private String name;
    private int age;

    public Student(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }
    @Override
    public int hashCode(){
    
    
        return name.hashCode() + age;
    }
}

For example, the return value is false

public class DeviceTest {
    
    
    public static void main(String[] args) {
    
    
        Student s1 = new Student("张三",1);
        Student s2 = new Student("张三",1);
        boolean result = s1.equals(s2);
        System.out.println(result);//false
    }
}

Override the equals() method

    @Override
    public boolean equals(Object obj) {
    
    
        if(this == obj) return true;
        //比较类的定义是否相等
        if(this.getClass() != obj.getClass()) return false;
        //类的定义一致,那么对象obj就可被强制转换为Student
        Student other = (Student) obj;
        return this.name.equals(other.name) && this.age == other.age;
    }
  • Compare memory addresses
  • Check if it is a uniform type
  • Checks if attributes are equal

Describe the difference between the == and equals methods:

Basic data types use == to compare whether the literals of two data are equal. Reference data types compare memory addresses using their equal signs.
The equals method comes from the Object class, and its implementation is also ==, and there is no difference between them at this time.
However, the equals method may be rewritten, and at this time the comparison needs to be carried out by looking at the rewriting logic

hashCode()和equals()

If the equals method is rewritten, then the hashCode method must be rewritten, because the hashCode method in the Object class will be called without rewriting the hashCode, and the memory address is obtained, and the memory addresses of different objects are different.
butAfter the equals method is rewritten, it is not the memory address that is compared, but the internal information of the object, otherwise it would result in multiple different objects being equal but having different hash codes

toString()

public String toString()

One should always consider overriding the toString() method in the class

The toString() method in Object returns a String representation of the object, which is useful for debugging.
The String representation of an object is entirely up to the object , that's why you override the toString method in your class

Then the above example:

public class DeviceTest {
    
    
    public static void main(String[] args) {
    
    
        Student s1 = new Student("张三",1);
        System.out.println(s1);
        Student s2 = new Student("张三",1);
        boolean result = s1.equals(s2);
        System.out.println(result);//false
    }
}

The result of printing s1 is:

org.device.Device.Student@bd2ea

Not Zhang San 1

Override the toString method

    @Override
    public String toString() {
    
    
        return name + "\t" + age;
    }

finalize()

protected void finalize() throws Throwable

The Object class provides a callback method finalize() that can be called on an object when it becomes garbage.
The finalize() implementation of the Object class does nothing – you can override finalize() to clean up, such as releasing resources

finalizeRewrite

    //当一个Student对象变成垃圾时可能会被调用
    @Override
    protected void finalize() throws Throwable {
    
    
        this.name = null;
        System.out.println("所有资源已释放完毕,可以进行清理了");
    }
public class DeviceTest {
    
    
    public static void main(String[] args) {
    
    
        show();
        //garbage collertor
        System.gc();
    }
    public static void show(){
    
    
        //s对象的作用范围只是在show()方法中
        //一旦方法执行完毕,那么s对象就应该消亡,释放内存
        Student s = new Student("李四",21);
        System.out.println(s);
    }
}

Only memory on the heap can generate garbage (nothing on the stack to reference it)

seven exceptions

unusual introduction

concept:

An exception is an event that occurs during program execution that interrupts the normal flow of program instructions

When an error occurs within a method, the method creates an object and hands it to the runtime system .
The object is called the exception object, which contains information about the error , including the type of error and the state of the program when the error occurred, creating an exception object and handing it to the runtime system is collectively referred to as throwing an exception

Exceptions are thrown by methods

Exception system:
insert image description here
Throwable
is the parent class of all exceptions, and its common methods are as follows:

public String getMessage();//获取异常发生的原因

public void printStackTrace();//打印异常在栈中的轨迹信息

Error

Error is a very serious error that programmers cannot solve by writing

Exception

It means abnormality, which is mainly caused by programmers' poor consideration when writing code. Exceptions are divided into two categories: runtime exceptions and check-time exceptions. Once these exceptions occur in the program, the programmer should deal with them

RuntimeException

It indicates a runtime exception. All exception types thrown when the program is running belong to the subclass of RuntimeException. Generally speaking, the program can automatically recover from runtime exceptions without having to deal with them.

check exception

Checked exceptions refer to the exceptions thrown by the compiler when it finds incorrect encoding in the process of compiling the code.

How to handle exceptions

In Java, there are many types of exceptions. If we need to remember each exception type, it is undoubtedly a very difficult thing. If there is a set of mechanisms to handle exceptions, it will reduce the time spent on development by programmers.
Java provides a set of exception handling mechanism to handle exceptions.
Java uses five keywords to handle exceptions:
throw
throws
try
catch
finally

throw throws an exception:

The throw keyword can only be used inside the method . The throw keyword throws an exception to indicate that it has not handled the exception

grammar:

throw 异常对象;//通常与if选择结构配合使用

Example:

import java.util.Scanner;

public class DeviceTest {
    
    
    private static Scanner sc = new Scanner(System.in);
    public static void main(String[] args) {
    
    
        calculate();
    }
    public static void calculate(){
    
    
        System.out.println("请输入一个数字");
        int number1 = sc.nextInt();
        System.out.println("请再输入一个数字");
        int number2 = sc.nextInt();
        if(number2 == 0){
    
    
            throw new ArithmeticException("除数不能为0");
        }
        int result = number1 / number2;
        System.out.println(result);
    }
}

Please enter a number
1
Please enter another number
0
Exception in thread “main” java.lang.ArithmeticException: The divisor cannot be 0
at org.device.Device.DeviceTest.calculate(DeviceTest.java:16)
at org.device.Device .DeviceTest.main(DeviceTest.java:8)

throw new ArithmeticException("除数不能为0");

Either way works

ArithmeticException e = new ArithmeticException("除数不能为0");
throw e;

throws declares the types of exceptions that may be thrown:

The throws keyword can only be applied to the definition of a method or constructor , and declares the types of exceptions that may be thrown. It will not handle the exception itself, and it will be handled by the method caller .
If the method caller does not handle it, the exception will continue to be thrown to the upper-level caller until the main() method. If the main() method is also unhandled, the program may be terminated.

grammar:

访问修饰符 返回值类型 方法名(参数列表) throws 异常类型1,异常类型2,....异常类型n{
    
    
}

Example:

import java.util.Scanner;

public class DeviceTest {
    
    
    private static Scanner sc = new Scanner(System.in);
    public static void main(String[] args) {
    
    
        deviced();
    }
    public  static int deviced() throws InterruptedException,ArithmeticException{
    
    
        int number1 = getNumber();
        int number2 = getNumber();
        return number1/number2;
    }
    public static int  getNumber()throws InterruptedException{
    
    
        System.out.println("请输入一个数字");
        int number = sc.nextInt();
        return number;
    }
}

throws can declare the types of exceptions that may be thrown during method execution, but it should be noted that only one exception can be thrown during method execution

try-catch catch exception:

Both the throw and throws keywords do not handle the exception, which may cause the program to terminate. In this case, the try-catch structure can be used to catch the thrown exception, so as to ensure that the program can run normally.

grammar:

try{
    
    
	//代码块
}catch(异常类型 异常对象名){
    
    
}

Among them, try means to try, try to execute the code block in the try structure, if an exception is thrown during the execution, it will be handed over to the catch statement block for capture operation

Example:

import java.util.Scanner;

public class DeviceTest {
    
    
    private static Scanner sc = new Scanner(System.in);
    public static void main(String[] args) {
    
    
        try{
    
    
            int number = deviced();
            System.out.println(number);
        }catch (InterruptedException e){
    
    
            e.printStackTrace();//打印异常轨迹
            System.out.println("请不要瞎搞");
        }
        System.out.println("发生异常也会执行");
    }
    public  static int deviced() throws InterruptedException,ArithmeticException{
    
    
        int number1 = getNumber();
        int number2 = getNumber();
        return number1/number2;
    }
    public static int  getNumber()throws InterruptedException{
    
    
        System.out.println("请输入一个数字");
        int number = sc.nextInt();
        return number;
    }
}

Multiple exception capture handling:

    public  static int deviced(){
    
    
        try{
    
    
            int number1 = getNumber();
            int number2 = getNumber();
            return number1/number2;
        }catch (InterruptedException e){
    
    
            System.out.println("请不要瞎搞");
        }catch (ArithmeticException e){
    
    
            System.out.println("除数不能为0");
        }
        return 0;
    }

When using multiple catch clauses to catch exceptions, if the data types of multiple caught exception objects have an inheritance relationship, then the parent class exception cannot be placed in front, just
like:

    int a = 100;
    if(a>100){
    
    

    }else(a>10){
    
    
        
    }

finally statement:
The finally statement cannot be used alone, and must be used in conjunction with the try statement or try-catch structure, which means that the program will be executed regardless of whether an exception occurs, and is mainly used to release resources.
However, if there is a system exit code in the try statement or catch statement, the finally statement will not be executed

System.exit(0);//系统正常退出
0正常退出,非0异常退出
System.exit(-1);//系统异常退出

grammar:

try{
    
    
} finally{
    
    
}

//或者

try{
    
    
} catch(异常类型 异常对象名){
    
    
}finally{
    
    
}

Example:

package org.device.Device;

public class DeviceTest {
    
    
    private static int[] numbers = {
    
    1,2,3,4,5};
    public static void main(String[] args) {
    
    
        try{
    
    
            int number = getNumber(5);
            System.out.println(number);
        }catch (ArrayIndexOutOfBoundsException e){
    
    
            System.out.println("数组下标越界了");
            System.exit(0);
        }finally {
    
    
            System.out.println("需要执行的代码");
        }
    }
    public static int getNumber(int index){
    
    
        return numbers[index];
    }
}

Thinking questions:

public class DeviceTest {
    
    
    public static void main(String[] args) {
    
    
        int result = getNumber();
        System.out.println(result);
    }
    public static int getNumber(){
    
    
        int number = 10;
        try{
    
    
            return number;
        }catch (Exception e){
    
    
            return 1;
        }finally {
    
    
            number++;
        }
    }
}

The result is:

10

try is to try to execute
return—> try to return a result, but find that there is a finally module behind, and the finally module will definitely be executed, so here we can only store the return value in a temporary variable, and then execute the finally module, finally module After the execution, return this temporary variable

custom exception

Why use custom exceptions?
In Java, there are many types of exceptions. If you want to use these exceptions, you must first be familiar with them. This is undoubtedly a huge workload and takes a lot of time.
If we can customize exceptions, we only need to be familiar with RuntimeException, Exception and Throwable.
This greatly narrows the scope, and custom exceptions can also help us quickly locate problems.

Custom runtime exception syntax:

public class 类名 extends RuntimeException{
    
    }

Custom checked exception syntax:

public class 类名 extends Exception{
    
    }

Example:
account login

package org.device.Device;

import javax.management.BadAttributeValueExpException;
import java.util.Scanner;

public class DeviceTest {
    
    
    public static Scanner sc = new Scanner(System.in);
    public static void main(String[] args){
    
    
        System.out.println("请输入账号");
        String  username = sc.next();
        System.out.println("请输入密码");
        String  password = sc.next();
        try {
    
    
            login(username,password);
        } catch (BadAttributeValueExpException e) {
    
    
            throw new RuntimeException(e);
        } catch (UsernameNotFound e) {
    
    
            throw new RuntimeException(e);
        } catch (BadCredentialsException e) {
    
    
            throw new RuntimeException(e);
        }
    }
    public static void login(String username,String password) throws BadAttributeValueExpException, UsernameNotFound, BadCredentialsException {
    
    
        if("admin".equals(username)){
    
    
            if("12345".equals(password)){
    
    
                System.out.println("登录成功");
            }else{
    
    
                throw new BadCredentialsException("账号或者密码错误");
            }
        }else{
    
    
            throw new UsernameNotFound("账号不存在");
        }
    }
}
package org.device.Device;

public  class UsernameNotFound extends Exception {
    
    
    public UsernameNotFound(){
    
    }
    public UsernameNotFound(String msg){
    
    
        super(msg);
    }
}
package org.device.Device;

public class BadCredentialsException extends Exception{
    
    
    public BadCredentialsException(){
    
    }
    public BadCredentialsException(String msg){
    
    
        super(msg);
    }
}

Exception usage notes:

  • Runtime exceptions may not be handled
  • If the parent class throws multiple exceptions, when the subclass overrides the parent class method, it can only throw the same exception or a subset of the exception (same as the covariant return type principle)
  • The parent class method does not throw an exception, and the subclass cannot throw a checked exception when overriding the method of the parent class. At this time, the subclass generates the exception, which can only be caught and processed, and cannot be declared to be thrown

Guess you like

Origin blog.csdn.net/weixin_72138633/article/details/131807453