Java 教程 在线

1372Java 面向对象 Java 继承

面向对象编程——继承和多态

//---引用我课堂老师的讲义(詹老师)

1、为什么使用继承

从已有的类派生出新的类,称为继承。

在不同的类中也可能会有共同的特征和动作,可以把这些共同的特征和动作放在一个类中,让其它类共享。

因此可以定义一个通用类,然后将其扩展为其它多个特定类,这些特定类继承通用类中的特征和动作。

继承是 Java 中实现软件重用的重要手段,避免重复,易于维护,易于理解。

2、父类和子类

如果类 B 从类 A 派生,或者说类 B 扩展自类 A,或者说类 B 继承类 A,

则称类 A 为"父类",也称为超类、基类;

称类 B 为"子类",也称为次类、扩展类、派生类。

子类从它的父类中继承可访问的数据域和方法,也可以添加新的数据域和新的方法。

定义继承的语法:

修饰符 class 子类名 extends 父类名

例如:Shape 类是父类,其子类可以有 Circle 类、Rectangle 类、Triangle 类,等等。

继承的注意点:

  • 子类不是父类的子集,子类一般比父类包含更多的数据域和方法。
  • 父类中的 private 数据域在子类中是不可见的,因此在子类中不能直接使用它们。
  • 继承是为"是一个"的关系建模的,父类和其子类间必须存在"是一个"的关系,否则不能用继承。
    但也并不是所有"是一个"的关系都应该用继承。例如,正方形是一个矩形,但不能让 Square 类来继承 Rectangle 类,因为正方形不能从矩形扩展得到任何东西。正确的继承关系是 Square 类继承 Shape 类
  • Java 只允许单一继承(即一个子类只能有一个直接父类),C++ 可以多继承(即一个子类有多个直接父类)。

3、super 关键字

super 表示使用它的类的父类。super 可用于:

  • 调用父类的构造方法;
  • 调用父类的方法(子类覆盖了父类的方法时);
  • 访问父类的数据域(可以这样用但没有必要这样用)。

调用父类的构造方法语法:

super();  

或   

super(参数列表);

注意:super 语句必须是子类构造方法的第一条语句。不能在子类中使用父类构造方法名来调用父类构造方法。 父类的构造方法不被子类继承。调用父类的构造方法的唯一途径是使用 super 关键字,如果子类中没显式调用,则编译器自动将 super(); 作为子类构造方法的第一条语句。这会形成一个构造方法链。

静态方法中不能使用 super 关键字。

调用父类的方法语法:

super.方法名(参数列表);

如果是继承的方法,是没有必要使用 super 来调用,直接即可调用。但如果子类覆盖或重写了父类的方法,则只有使用 super 才能在子类中调用父类中的被重写的方法。

4、this 关键字

this 关键字表示当前对象。可用于:

  • 调用当前类的构造方法,并且必须是方法的第一条语句。如:this(); 调用默认构造方法。this(参数); 调用带参构造方法。
  • 限定当前对象的数据域变量。一般用于方法内的局部变量与对象的数据域变量同名的情况。如 this.num = num。this.num 表示当前对象的数据域变量 num,而 num 表示方法中的局部变量。

1371Java 面向对象 Java 继承

java 中若要在子类调用父类的方法,需使用关键字super。

实例

class Animal{
    void go(){
        System.out.println("animal go");
    }
}

class Dog extends Animal{
    void go(){
        //调用父类方法
        super.go();
    }
}

//驱动函数
public static void  main(String[] args){
    Dog dog=new Dog();
    dog.go();
}

输出结果:

animal go

1370Java 异常处理

1.检查型异常(Checked Exception)

个人理解:所谓检查(Checked)是指编译器要检查这类异常,检查的目的一方面是因为该类异常的发生难以避免,另一方面就是让开发者去解决掉这类异常,所以称为必须处理(try ...catch)的异常。如果不处理这类异常,集成开发环境中的编译器一般会给出错误提示。

例如:一个读取文件的方法代码逻辑没有错误,但程序运行时可能会因为文件找不到而抛出FileNotFoundException,如果不处理这些异常,程序将来肯定会出错。所以编译器会提示你要去捕获并处理这种可能发生的异常,不处理就不能通过编译。

2.非检查型异常(Unchecked Exception)

个人理解:所谓非检查(Unchecked)是指编译器不会检查这类异常,不检查的则开发者在代码的编辑编译阶段就不是必须处理,这类异常一般可以避免,因此无需处理(try ...catch)。如果不处理这类异常,集成开发环境中的编译器也不会给出错误提示。

例如:你的程序逻辑本身有问题,比如数组越界、访问null对象,这种错误你自己是可以避免的。编译器不会强制你检查这种异常。

1369Java 异常处理

throws 用于方法上,可抛出多个异常,每个异常的类名用逗号隔开。

try...catch.... 捕获异常时,大的异常(Exception类)放在下方,小的异常放在上方,否则,在异常捕获时,小的异常将不能被捕获,因为全在大的异常类中捕获到。

即: 如果多个 catch 块中的异常出现继承关系,父类异常 catch 块放在最下面。

处理异常的方式,不可以直接打印,或者直接输出,正确的处理方式:

  • 1.根据异常情况处理对应的逻辑
  • 2.使用文件记录异常,便于日后查看
class FuShuException extends Exception
{
    private int value;

    FuShuException() {
        super();
    }

    FuShuException(String msg, int value) {
        super(msg);//调用父类有参构造,获得异常信息
        this.value = value;
    }

    public int getValue() {
        return value;
    }

}

class Demo {
    int div(int a, int b) throws FuShuException {
        if (b < 0)
            throw new FuShuException("出现了除数是负数的情况by fushu", b);// 手动通过throw关键字抛出一个自定义异常对象。
        return a / b;
    }
}

public class MyT {
    public static void main(String[] args) {
        Demo d = new Demo();
        try {
            int x = d.div(4, -9);
            System.out.println("x=" + x);
        } catch (FuShuException e) {
            System.out.println(e.toString());
            System.out.println("错误的负数是:" + e.getValue());
        }catch (Exception e) {//大的异常放在下方,小的异常放在上方
            System.out.println(e.getMessage());
        }

        System.out.println("end");

    }
}

1368Java 异常处理

throws 用在函数上,声明该函数的功能可能会出现问题。

将异常抛出,是问题暴露出来,用于处理。

可以抛给虚拟机处理,或者使用 try....catch... 进行处理。虚拟机的处理方式,就是将异常打印出来,并且将在异常处的代码终止。

throw 用在代码块中,后面跟着异常的对象,该对象可以是自定义异常,且 throw 使用在方法中。

class FuShuException extends Exception //getMessage();
{
    private int value;
    FuShuException()
    {
        super();
    }
    FuShuException(String msg,int value)
    {
        super(msg);
        this.value = value;
    }
    public int getValue()
    {
        return value;
    }
}

class Demo
{
    int div(int a,int b)throws FuShuException
    {
        if(b<0) {
             // 手动通过throw关键字抛出一个自定义异常对象。
            throw new FuShuException("出现了除数是负数的情况------ / by fushu",b);
        }
        return a/b;
    }
}

class  ExceptionDemo3
{
    public static void main(String[] args)
    {
        Demo d = new Demo();
        try
        {
            int x = d.div(4,-9);
            System.out.println("x="+x);
        }
        catch (FuShuException e)
        {
            System.out.println(e.toString());
            //System.out.println("除数出现负数了");
            System.out.println("错误的负数是:"+e.getValue());
        }
        System.out.println("over");
    }
}