java基础八 继承和异常处理

Java继承概述

1.多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些相同属性和行为,只要继承那个类即可。

2.在Java中通过extends关键字可以实现类与类的继承。

例如:class 子类名 extends 父类名 {}

3.单独的这个类称为父类,基类或者超类;这多个类可以称为子类或者派生类。

4.有了继承以后,我们定义一个类的时候,可以在一个已经存在的类的基础上,还可以定义自己的新成员

类的继承格式

在 Java 中通过 extends 关键字可以申明一个类是从另外一个类继承而来的,一般形式如下:


class 父类 {
}
 
class 子类 extends 父类 {
}

继承案例
动物父类


ublic class Animal {
    
     private Integer age;   //
    
     public Animal(){
         System.out.println("Animal construct method");
     }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
     
    public void eat(){
        System.out.println("eat food");
    }
}

狗子类

public class Dog extends Animal{     //class 子类名 extends 父类名 
     private String color; //毛色,	/可以定义特有属性
     
     public Dog(String color){  //可以定义特有属性
         this.color = color;
     }
     
     public void run(){     //可以定义特有属性
         System.out.println("Dog is running");
     }
     
     @Override
     public void eat(){                             
        System.out.println("dog eat bone");    //可以重写父类有的方法
     }
}

继承的特性

  • 子类拥有父类非 private 的属性、方法。
  • 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
  • 子类可以用自己的方式实现父类的方法。
  • Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 A 类继承 B 类,B 类继承 C
    类,所以按照关系就是 C 类是 B 类的父类,B 类是 A 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
  • 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)

从这两段代码可以看出来,代码存在重复了,导致后果就是代码量大且臃肿,而且维护性不高(维护性主要是后期需要修改的时候,就需要修改很多的代码,容易出错),所以要从根本上解决这两段代码的问题,就需要继承,将两段代码中相同的部分提取出来组成 一个父类,如果有相同的方法和属性,则不必重复

继承类型

在这里插入图片描述

super 与 this 关键字

super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。

this关键字:指向自己的引用。


class Animal {
  void eat() {
    System.out.println("animal : eat");
  }
}
 
class Dog extends Animal {
  void eat() {
    System.out.println("dog : eat");
  }
  void eatTest() {
    this.eat();   // this 调用自己的方法
    super.eat();  // super 调用父类方法
  }
}
 
public class Test {
  public static void main(String[] args) {
    Animal a = new Animal();
    a.eat();
    Dog d = new Dog();
    d.eatTest();
  }
}

运行结果

animal : eat
dog : eat
animal : eat

final关键字

final 关键字声明类可以把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写:

声明类:

final class 类名 {//类体}

声明方法:

修饰符(public/private/default/protected) final 返回值类型 方法名(){//方法体}

抽象类

抽象类

  • 抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
  • 由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用
  • 抽象类一般用来作为一个父类,但是里面可以有方法是抽象的,以让子类来实现。
  • abstract 修饰符,表示这个类是一个抽象类
    • 抽象类和普通类的区别: 抽象类中可以有抽象方法(只有方法定义,没有方法体,并且抽象类无法实例化)
      抽象方法
  • 如果你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法。
  • Abstract 关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体。
  • 抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。

抽象类的声明

   public abstract class AbstractPerson {
    	
	public String name;
	public int age;
	
	//abstract 声明这个方法是一个抽象方法
	public abstract void say();
	
	public void eat() {
		System.out.println("正在吃饭......");
	}
	
}

继承了抽象类的子类

public class JapaneseExtendsAbstractPerson extends AbstractPerson{

	/**
	 * 子类中必须实现抽象类中的抽象方法
	 */
	@Override
	public void say() {
		System.out.println("雅蠛蝶");
	}
}

抽象类总结规定

  1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。

  2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。

  3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。

  4. 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。

  5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。

异常及其异常处理

异常的结构图在这里插入图片描述
1.所有的异常都是从Throwable继承而来的,是所有异常的共同祖先。

2.Throwable有两个子类,Error和Exception。 错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的

3.Exception,是另外一个非常重要的异常子类。它规定的异常是程序本身可以处理的异常。异常和错误的区别是,异常是可以被处理的,而错误是没法处理的。**
4 检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
5运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
6.Exception是所以异常的父类,可以捕捉所有异常

异常发生的原因有很多,通常包含以下几大类:

  • 用户输入了非法数据

  • 要打开的文件不存在。

  • 网络通信时连接中断,或者JVM内存溢出。

这些异常有的是因为用户错误引起,有的是程序错误引起的,还有其它一些是因为物理错误引起的。

常见的异常

java.lang.*下的异常:

1、Java.lang.NullPointerException

空指针异常:调用了未经初始化的对象或者是不存在的对象。

2、 java.lang.ClassNotFoundException

类不存在异常:类的名称和路径不正确。

3、 java.lang.NumberFormatException

字符串转换为数字异常。

4、java.lang.IndexOutOfBoundsException

数组下标越界异常。

5、java.lang.IllegalArgumentException

不合法的参数异常。

6、java.lang.IllegalAccessException

没有访问权限异常。

7、java.lang.ArithmeticException

数学运算异常。

8、java.lang.ClassCastException

数据类型转换异常。

9、java.lang.InterruptedException

线程中断异常。

10、java.lang.OutOfMemoryException

内容不足异常。

11、java.lang.NoClassDefFoundException

类未定义异常。

12、java.lang.NoSuchMethodException

方法不存在异常。

13、java.lang.NoSuchFiledException

属性不存在异常。

java.io.*下的异常:

14、Java.io.IOException

输入输出异常。

15、java.io.FileNotFoundException

文件不存在异常。

java.net.*下的异常:

16、Java.net.ConnectException

网络连接异常。

17、Java.net.SocketTimeoutException

网络连接超时异常。

java.rmi.*下的异常:

18、Java.rmi.ServerRuntimeException

服务器运行异常。

java.text.*下的异常:

19、Java.sql.SQLException

sql执行异常。

java.text.*下的异常:

20、Java.text.ParseException

转换异常。

捕获异常

使用 try 和 catch 关键字可以捕获异常。try/catch 代码块放在异常可能发生的地方。

try/catch代码块中的代码称为保护代码,使用 try/catch 的语法如下

try
{
   // 程序代码
}catch(ExceptionName e1)
{
   //Catch 块
}

Catch 语句包含要捕获异常类型的声明。当保护代码块中发生一个异常时,try 后面的 catch 块就会被检查。

如果发生的异常包含在 catch 块中,异常会被传递到该 catch 块,这和传递一个参数到方法是一样。
实例

下面的例子中声明有两个元素的一个数组,当代码试图访问数组的第三个元素的时候就会抛出一个异常。


// 文件名 : ExcepTest.java
import java.io.*;
public class ExcepTest{
 
   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);
      }
      System.out.println("Out of the block");
   }
}

编译结果

Exception thrown  :java.lang.ArrayIndexOutOfBoundsException: 3
Out of the block

多重捕获块

一个 try 代码块后面跟随多个 catch 代码块的情况就叫多重捕获。

多重捕获块的语法如下所示:


try{
   // 程序代码
}catch(异常类型1 异常的变量名1){
  // 程序代码
}catch(异常类型2 异常的变量名2){
  // 程序代码
}catch(异常类型2 异常的变量名2){
  // 程序代码
}

上面的代码段包含了 3 个 catch块。

可以在 try 语句后面添加任意数量的 catch 块。

如果保护代码中发生异常,异常被抛给第一个 catch 块。

如果抛出异常的数据类型与 ExceptionType1 匹配,它在这里就会被捕获。

如果不匹配,它会被传递给第二个 catch 块。

如此,直到异常被捕获或者通过所有的 catch 块。
实例

该实例展示了怎么使用多重 try/catch。

try {
    file = new FileInputStream(fileName);
    x = (byte) file.read();
} catch(FileNotFoundException f) { // Not valid!
    f.printStackTrace();
    return -1;
} catch(IOException i) {
    i.printStackTrace();
    return -1;
}

finally关键字

finally 关键字用来创建在 try 代码块后面执行的代码块。

无论是否发生异常,finally 代码块中的代码总会被执行。

在 finally 代码块中,可以运行清理类型等收尾善后性质的语句。

finally 代码块出现在 catch 代码块最后,语法如下:

try{
  // 程序代码
}catch(异常类型1 异常的变量名1){
  // 程序代码
}catch(异常类型2 异常的变量名2){
  // 程序代码
}finally{
  // 程序代码
}

实例

public class ExcepTest{
  public static void main(String args[]){
    int a[] = new int[2];
    try{
       System.out.println("Access element three :" + a[3]);
    }catch(ArrayIndexOutOfBoundsException e){
       System.out.println("Exception thrown  :" + e);
    }
    finally{
       a[0] = 6;
       System.out.println("First element value: " +a[0]);
       System.out.println("The finally statement is executed");
    }
  }
}

以上实例编译运行结果如下:

Exception thrown  :java.lang.ArrayIndexOutOfBoundsException: 3
First element value: 6
The finally statement is executed

注意下面事项:

catch 不能独立于 try 存在。
在 try/catch 后面添加 finally 块并非强制性要求的。
try 代码后不能既没 catch 块也没 finally 块。
try, catch, finally 块之间不能添加任何代码。

抛出异常

抛异常可以直接抛给jvm: 就是说,在main方法中,不对可能出现异常的代码进行try-catch

下层方法可以把异常抛给上层调用者

比如:定义一个方法,求商,方法声明会抛出异常,则在调用该方法时会出现提醒让其使用try-catch

public static int divide(int a,int b) throws Exception{
	return a/b;
}

然后有两种情况使用
情况一, 可以选择继续往上抛

// divide方法的调用者就能获得提示:如何处理异常
// 可以选择继续往上抛
main thows Exception {
	
	divide(5,0);

}

情况二,也可以选择将异常抓住,不再外抛了

main{
	
	try{
	   divide(5,0);
	}catch(Exception e){
	   sysout(e.getMessage());
	}
	
}

throw 抛出异常

当程序运行时数据出现错误或者我们不希望发生的情况出现的话,可以通过抛出异常来处理。

异常抛出语法:

throw new 异常类();

在 /home/project/ 目录下新建 ThrowTest.java

public class ThrowTest {

    public static void main(String[] args) {
        Integer a = 1;
        Integer b = null;
        //当a或者b为null时,抛出异常
        if (a == null || b == null) {
            throw new NullPointerException();
        } else {
            System.out.println(a + b);
        }
    }
}
$ javac ThrowTest.java
$ java ThrowTest
Exception in thread "main" java.lang.NullPointerException
    at ThrowTest.main(ThrowTest.java:8)

throws 声明异常

throws 用于声明异常,表示该方法可能会抛出的异常。如果声明的异常中包括 checked 异常(受检异常),那么调用者必须捕获处理该异常或者使用 throws 继续向上抛出。throws 位于方法体前,多个异常之间使用 , 分割。

修改 /home/project/ 下的 ThrowsTest.java:

import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class ThrowsTest {

    public static void main(String[] args) throws FileNotFoundException {
        //由方法的调用者捕获异常或者继续向上抛出
        throwsTest();

    }

    public static void throwsTest() throws FileNotFoundException {
        new FileInputStream("/home/project/shiyanlou.file");
    }
}

编译运行:

$ javac ThrowsTest.java
$ java ThrowsTest
Exception in thread "main" java.io.FileNotFoundException: /home/project/shiyanlou.file (系统找不到指定的路径。)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(FileInputStream.java:195)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at ThrowsTest.throwsTest(ThrowsTest.java:13)
    at ThrowsTest.main(ThrowsTest.java:8)
 [copy] 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java是一种面向对象的编程语言,它的设计理念是“一次编写,到处运行”。Java语言具有跨平台的特性,这是由于Java虚拟机(JVM)的存在,可以将Java代码编译成字节码,在不同的平台上运行。Java基础理论包括以下几个方面: 1. Java语言的特性:Java语言具有面向对象、简单易学、跨平台、安全可靠、高性能等特点。 2. Java虚拟机(JVM):JVM是Java程序的运行环境,它能够将Java字节码转换成可执行的机器码,并提供内存管理、垃圾回收、线程管理等功能。 3. Java类和对象:Java是一种面向对象的编程语言,类是Java程序的基本单位,对象是类的实例。 4. Java接口和抽象类Java中的接口和抽象类是实现多态性的重要手段,它们都可以用来定义抽象类型。 5. Java异常处理Java提供了异常处理机制,可以有效地处理程序运行时出现的异常情况。 6. Java多线程编程:Java提供了多线程编程的支持,可以使程序并发执行,提高程序的效率。 Java的设计原理包括以下几个方面: 1. 面向对象设计原则:Java的设计基于面向对象的思想,封装、继承、多态是Java面向对象设计的基本原则。 2. 设计模式:Java的设计模式是对软件设计中常见问题的通用解决方案,Java中常见的设计模式包括单例模式、工厂模式、观察者模式等。 3. SOLID原则:SOLID是面向对象设计的五个基本原则,包括单一职责、开闭原则、里氏替换、接口隔离和依赖反转。 4. 设计与实现的分离:Java的设计强调设计与实现的分离,设计应该独立于实现,使得程序的可维护性和可扩展性更好。 5. 高内聚低耦合:Java的设计强调高内聚低耦合,即模块内部的各个元素紧密联系,模块之间的依赖关系尽可能的少。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值