Day10面向对象4 异常、抽象类、接口、面向抽象/接口编程

1、异常

 

Throwsable--异常的顶级父类

      ---Error--系统异常,我们解决不了,比如:栈溢出异常

      ---Exception--可以通过编程解决的异常

                 --编译时异常--比如:括号写错了,压根就不通过编译

                --运行时异常--RunTimeException--比如:输入不匹配异常/算术异常

2、异常的处理方案:

1).捕获处理

格式: try{

               可能会出现异常的代码

}catch(Exception  e){//我们预测到可能会发生的异常类型

               解决方案

   }

TIPS:catch捕获处理异常是可以嵌套的

           一般用Exception首尾,担心会有未想到的其他异常,所以做通用解决方案,也可以只写一个Exception,那么其他异常均不作特殊处理,统一处理。

2).向上抛出  throws

格式:在方法声明的两个括号之间,加 “throws  异常类型1,异常类型2,...”,多个异常类型用逗号隔开

注意:不能把问题抛给main(),因为没有人解决了,所以要在main()调用之前解决

比如案例中:method3()会抛出异常,所以先用f()调用method3捕获处理异常

                     再由main()调用f()执行method3()的功能

                     f()的作用:f()用来捕获处理method3()的异常

练习:异常测试

package cn.tedu.exception;

import java.util.InputMismatchException;
import java.util.Scanner;

/*本类用作测试异常的入门案例*/
public class ExceptionDemo {
    public static void main(String[] args) {
        //method1();//调用method1方法--人为暴露异常--简单看看异常长什么样
        method2();//调用method2方法--异常解决方案1--捕获处理--自己解决
       // method3();//调用method3--异常解决方案2--向上抛出--交给调用
        f();//为了写一个标准的写法,在main()调用之前解决异常
    }

    private static void f() {
        try{
            method3();
        }catch (Exception e){
            System.out.println("请输入正确的数据!");
        }
    }
    /*如果一个方法抛出了异常,那么谁调用这个方法,谁就需要处理这个异常
    * 这里的处理也有两种方案:捕获解决和继续向上抛出
    * 但是注意:我们一般会在main()调用之前解决异常
    * 而不是把问题抛给main()方法,因为没人解决了,详见本类f()调用method3()*/

    //6.创建method3(),异常解决方案2
    /*异常抛出的格式:在小括号与大括号之间写:throws 异常类型1,异常类型2,...
    *若有多个异常,使用逗号隔开*/
    private static void method3()
            throws InputMismatchException,ArithmeticException,Exception {
        //7.1复写刚刚的代码
        System.out.println("请输入你要计算的一个整数:");
        int a = new Scanner(System.in).nextInt();
        System.out.println("请输入你要计算的第二个整数");
        int b = new Scanner(System.in).nextInt();
        System.out.println(a/b);
    }

    /*异常捕获处理的格式:
    * try{
    *    可能会抛出异常的代码
    * }catch(异常类型  异常的名字){
    *    捕获到了异常,进行处理的解决方案
    * }
    * */
    //创建方法用来捕获处理异常--自己处理
    private static void method2() {
        //5.按照捕获处理的语法提供异常解决方案1
        /*4.try中放着的是可能会出现异常的代码
        * 5.如果发生异常,就会被捕获,执行之前catch中提供的解决方案*/
        try{
            //5.2复写刚刚的代码
            System.out.println("请输入你要计算的一个整数:");
            int a = new Scanner(System.in).nextInt();
            System.out.println("请输入你要计算的第二个整数");
            int b = new Scanner(System.in).nextInt();
            System.out.println(a/b);
        }//catch(InputMismatchException e){//注意:异常类型要导包import class
//            System.out.println("请输入规定的整数类型!");
//        }catch(ArithmeticException e){
//            System.out.println("除数不能为0,请重新输入");
//      }
        catch(Exception e){//可以直接使用Exception异常类型进行捕获处理,因为它包含--RunTimeException、ClassCastException、ClassNotFoundException
            System.out.println("您输入的不对!请重新输入!");
        }
        /*6.try-catch可以嵌套,若有多种异常类型需要特殊处理的话
        *7.这就是多态最为经典的一种用法,我们并不关心子类的具体类型
        * 而是将所有子类统一当作父类类型来处理,提供通用的解决方案*/
    }

    private static void method1() {
        //.提示并接收用户输入的第一个数
        System.out.println("请输入你要计算的一个整数:");
        int a = new Scanner(System.in).nextInt();
        //2.提示并接受用户输入的第二个整数
        System.out.println("请输入你要计算的第二个整数");
        int b = new Scanner(System.in).nextInt();
        //3.直接打印这两个数除法的结果
        System.out.println(a/b);
        //输入3和3.2,报错:InputMismatchException--输入不匹配异常
        //输入17和0,报错:ArithmeticException--算术异常,除数不能为零是数学规定
        /*1.不要害怕BUG,真正的勇士敢于直面自己写的BUG
        * 2.学会看报错的信息提示,确定自己的错误方向
        * 3.学会看报错的行号信息,确认自己报错的位置,哪里不对点哪里
        * 注意:源码不会错,要看的是自己写的代码*/
    }
}

2.抽象类

abstract   关键字

分为:

1).修饰类--被abstact修饰的类是抽象类

2).修饰方法--被abstract修饰的方法是抽象方法(指的是对普通方法的修饰)

格式:

注意:没有方法体

1》有抽象方法的类一定是抽象类,但是抽象类可以没有抽象方法

2》抽象类中既可以都是普通方法,也可以都是抽象方法,还可以混着来

3》抽象类不可以实例化(创建自己的对象),但是抽象类有构造方法,为了子类创建对象时调用

4》如果一个类继承了抽象类,那么:

     方案一:继续抽象,作为抽象子类

     方案二:实现抽象父类中的(所有!!!)抽象方法

5》创建时如果想使用父类,那么可以创建多态父类对象进行测试

练习:抽象类测试的入门案例

package cn.tedu.oop;
/*本类用于抽象类测试的入门案例*/
public class AbstractDemo {
    public static void main(String[] args) {
        /*4.抽象类不可以实例化(创建对象)!!!*/
        //5.1测试抽象父类是否可以创建对象
        //Animal a = new Animal();//不可以
        //5.2创建多态对象进行测试
        Animal a = new Pig();
        a.eat();//调用抽象父类普通方法--可以
        a.fly();//调用抽象父类抽象方法--可以
    }
}
//1.创建父类Animal
/*2.被abstract修饰的类是抽象类
* 若一类中包含抽象方法,那这个类必须被声明成抽象类*/
//4.2添加抽象方法后,此类必须也变成抽象类
abstract class Animal{
    //3.创建普通方法--功能
    public void eat(){
        System.out.println("吃啥都行~");
    }
    public void play(){
        System.out.println("玩啥都行!!");
    }
    //4.1创建抽象方法
    /*1.被abstract修饰的方法是抽象方法,且抽象方法没有方法体*/
    public abstract void fly();
    public abstract void fly2();

}
//2.创建子类Pig,继承父类Animal
/*3.当一个子类继承了抽象父类以后,有两种解决方案:
* 方案一:变成抽象类,“子类也不实现,继续抽象”
* 方案二:实现抽象父类中的所有抽象方法,“父债子偿”*/
//4.3子类需要处理。继续抽象/实现父类所有抽象方法
//abstract class Pig extends Animal{//方案一:子类也变成抽象类
class Pig extends Animal{//方案二:implement method()
    @Override//注解,标识这是一个重写的方法
    public void fly() {
        System.out.println("父债子偿");
    }

    @Override
    public void fly2() {
        System.out.println("抽象父类中的所有抽象方法都需要子类来实现");
    }

}

练习:抽象类中建立成员变量、final常量和普通方法

package cn.tedu.oop;
/*本类用于抽象类中的成员测试*/
public class AbstractDemo3 {
}
//1.创建抽象父类Fruit
abstract class Fruit{
    /*1.抽象类中可以定义成员变量吗--可以*/
    int sum = 100;
    /* 2.抽象类可以定义成员常量吗--可以*/
    final String name = "xiao huang ren";
    /*3.抽象类中可以定义普通方法吗?--可以
    * 抽象类中可以都是普通方法吗?--也可以
    * 4.如果一个类中都是普通方法,那为什么它还要修饰成抽象类呢?
    * 答:因为抽象类不可以实例化,所以如果不想让外界创建本类的对象
    * 就可以把普通类声明成抽象类*/
    public void clean(){
        System.out.println("水果还是要洗洗再吃~~~");
    }
    /*5.抽象类中可以定义抽象方法吗?--可以
    * 6.若类中添加了抽象方法,那么这个类必须被声明成抽象类*/
    public abstract void grow();
    public abstract void breath();

}
//2.创建子类Banana,继承父类Fruit
class Banana extends Fruit{//使用方案二:implement method()创建父类中抽象方法的具体方法

    @Override
    public void grow() {
        System.out.println("一串香蕉老沉了~~");
    }

    @Override
    public void breath() {
        System.out.println("香蕉不用洗");

    }
}

3.接口

1.概念:接口( Interface )在Java中也是一种抽象类型,接口中的内容是抽象形成的需要实现的功能,接口更像是一种规则和一套标准.

2.接口的关键字是interface

3.我们通过implements建立接口与接口实现类的关系InterImpl implements Inter{ }

4.接口可以看作是一种特殊的抽象类,因为他里面全是抽象方法

5.实现子类如果与父类接口建立了实现关系,有两种方案:

     方案一:继续抽象--》抽象子类

     方案二:不再抽象-->实现父类接口中所有的抽象方法

6.接口没有构造方法,实现子类可以创建对象的原因是调用了Object顶级父类的无参构造

TIPS:问题:子类在创建对象时,默认会调用父类的无参构造

                    那么如果接口的实现类在没有明确指定父类时,使用的是哪个构造方法呢?

          答案:默认继承顶级父类Object,所以实现类的构造方法中super();调用的是Object类的无参构造

7.接口中没有普通成员变量,有的只是静态常量,所以当你定义int age =10;时默认添加public static final int age =10;

练习-1:创建接口

创建包: cn.tedu.inter
创建接口:Inter.java

package cn.tedu.inter;
/*本接口用于创建测试
* 1.我们通过interface关键字来定义接口*/
public interface Inter {
    /*2.接口中可以定义普通方法吗?--不可以*/
    //public void play(){}
    /*3.接口中可以有抽象方法吗?--可以,接口中的方法都是抽象方法*/
    public abstract void paly();
    public abstract void eat();
}

练习-2:创建接口实现类

创建包: cn.tedu.inter
创建接口实现类:InterImpl.java

package cn.tedu.inter;
/*本类作为Inter接口的实现类
* 1.实现类如果想要和接口建立实现关系,就通过implements来实现
* 2.接口实现类 与接口建立关系以后,有两种解决方案:
* 方案一:添加abstract ,变成抽象子类,不实现任何抽象方法
* 方案二:implement methods,继续作为普通子类,实现父类接口的所有的抽象方法*/
//abstract public  class InterImpl implements Inter {方案一:添加abstract
 public  class InterImpl implements Inter {//方案二:implement methods
    @Override
    public void paly() {
        System.out.println("划龙舟!");
    }

    @Override
    public void eat() {
        System.out.println("吃粽子~");
    }
}

练习-3:创建接口测试类

创建包: cn.tedu.inter
创建接口测试类:InterTests.java

package cn.tedu.inter;
/*本类用于测试接口的实现*/
public class InterTests {
    //创建程序的抽象入口函数main()方法
    public static void main(String[] args) {
        //测试创建接口对象
        /*接口可以创建对象吗?--不可以*/
        //Inter i =new Inter();

        //创建多态对象进行测试
        Inter i = new InterImpl();//接口Inter是父类,InterImpl是子类
        i.eat();
        i.paly();

        //创建子类对象进行测试
        InterImpl i2 = new InterImpl();
        i2.eat();
        i2.paly();
    }
}

3.1接口的用法

练习:测试接口中能使用什么?

接口中只能有静态常量和抽象方法,不能有成员变量、构造方法、普通方法。

package cn.tedu.inter2;
/*本类用于进一步测试接口的使用、构造方法*/
public class TestUserInter {
    public static void main(String[] args) {
        //创建多态对象进行测试
        Inter2 i = new Inter2Impl();
        //接口中的变量实际上都是静态的,因为可以通过类名直接调用
        System.out.println(Inter2.age);
        //接口中的变量都是常量,因为不可以被重新赋值
        //Inter2.age = 30;
    }

}
//1.创建接口
interface Inter2{
    /*1.接口中有构造方法吗?--没有,且不可以创建*/
    //public Inter2(){}
    /*2.接口中可以有成员变量吗?--没有
    * 实际上是一个静态常量,实际的写法public static final int age = 10;
    * 在接口中可以省略不写,接口中都是静态常量 */
    //接口中的变量实际上都是常量,因为必须初始化(赋值)
    int age = 10;
    /*3.接口里可以有抽象方法吗?--可以!全是
    * 方法定义可以简写,默认自动拼接public abstract*/
    public abstract void eat();
    void eat2();
}
//2.创建接口实现类
/*如果一个类没有明确指定父类,那么它的父类就是Object顶级父类,默认存在此现象*/
//class Inter2Impl extends Object implements Inter2 {
class Inter2Impl implements Inter2 {
    //3.创建子类的构造方法
    public Inter2Impl(){
        super();//表示调用的是父类Object的无参构造
        System.out.println("我是实现类Inter2Impl的构造方法~");
    }
    //如果普通子类实现了接口,需要实现接口中的所有抽象方法
    @Override
    public void eat() {

    }

    @Override
    public void eat2() {

    }
}

总结:

1.接口里是没有构造方法的,在创建实现类的对象时默认的super(),是调用的默认Object的无参构造

2.接口里没有成员变量,都是常量。所以,你定义一个变量没有写修饰符时,默认会加上:public static final

3.接口里的方法,默认就都是抽象的,如果你不写明是abstract的,那会自动补齐。例如:public abstract void save

3.2 面向抽象编程

package cn.tedu.design;
/*本类设计老师类,要求:面向抽象编程--后天向上抽取形成的结果*/
public class DesignTeacher1 {
    public static void main(String[] args) {
        //创建子类对象进行测试
        CGBTeacher ct = new CGBTeacher();
        ct.ready();
        ct.teach();

        ACTeacher at = new ACTeacher();
        at.ready();
        at.teach();

        SCDTeacher st = new SCDTeacher();
    }
}

//三个老师类都有共性内容,所以创建一个父类老师,让他们三个继承,就都可以使用了
abstract class Teacher{
    int id;
    String name;

    public abstract void ready();//由于后面三个老师讲课内容会改变,需要重写
    public abstract void teach();//改变成抽象类、抽象方法
}
//1.创建培优老师类--冗余
class CGBTeacher extends Teacher{//implement methods

    @Override
    public void ready() {
        System.out.println("正在备课...电商项目");
    }

    @Override
    public void teach() {
        System.out.println("正在讲课...电商项目");
    }
}
class ACTeacher extends Teacher{

    @Override
    public void ready() {
        System.out.println("正在备课...加强模块");
    }

    @Override
    public void teach() {
        System.out.println("正在讲课...加强模块");
    }
}
class SCDTeacher extends Teacher{

    @Override
    public void ready() {
        System.out.println("正在备课...hadoop");
    }

    @Override
    public void teach() {
        System.out.println("正在讲课...hadoop");
    }
}

3.3面向接口编程

package cn.tedu.design;
//刚刚的Teacher1案例:面向抽象编程--后天向上抽取形成的结果
/*本类用于设计老师类,要求:面向接口编程--先天设计的结果*/
public class DesignTeacher2 {
}
//1.创建接口,设计形成父级接口--接口体现的是预先定义好的规则
interface Teacher2{
    void ready();
    void teach();
}
//2.创建接口实现类
class CGBTeacher2 implements Teacher2{

    @Override
    public void ready() {
        System.out.println(1);
    }

    @Override
    public void teach() {
        System.out.println(2);
    }
}

3.4接口的多继承多实现

package cn.tedu.inter;
/*本类测试接口相关的复杂关系*/
public class InterDemo {
    public static void main(String[] args) {
        //多态对象
        Inter3 i3 = new Inter3Impl();
        i3.add();
        //创建实现类对象进行测试--最常用
        Inter3Impl inter3 =new Inter3Impl();

    }
}
/*1.定义接口关键字:interface,
接口不是类,可以看作是一个内部全是抽象方法的特殊抽象类*/
interface Inter1{
    /*2.接口中有成员变量吗?没有!会默认拼接public static final,静态常量*/
     int age = 10;
     /*3.接口中的方法都是抽象方法,默认拼接public abstract,所以可以简写*/
    void update();//更新
    void find();//查询
}
interface Inter2{
    /*4.接口没有构造方法,不可以实例化(创建对象)*/
    void delete();//删除
    void add();//新增
}
/*接口与接口是继承关系,且一个接口可以继承多个接口*/
interface Inter3 extends Inter1,Inter2{ }//实现多个接口
/*类与接口是实现(implements)的关系,且一个类可以实现多个接口*/
class Inter3Impl implements Inter3{//实现一个接口

    @Override
    public void update() {
        System.out.println("更新");
    }

    @Override
    public void find() {
        System.out.println("发现");
    }

    @Override
    public void delete() {
        System.out.println("删除");
    }

    @Override
    public void add() {
        System.out.println("新增");
    }
}

3.5总结


1. 类与类的关系
继承关系,只支持单继承
比如,A是子类 B是父类,A具备B所有的功能(除了父类的私有资源和构造方法)
子类如果要修改原有功能,需要重写(方法名+参数列表与父类一致 ,子类权限修饰符>=父类修饰符)

2. 类和接口的关系
实现关系.可以单实现,也可以多实现
class A implements B,C{};或者class D implements B,C{ }-->class A implements D{}
其中A是实现类,B和C是接口,A拥有BC接口的所有功能,只是需要进行方法的重写,否则A就是抽象类

3. 接口与接口的关系
是继承关系,可以单继承,也可以多继承
interface A extends B,C{}
其中ABC都是接口,A是子接口,具有BC接口的所有功能(抽象方法)
class X implements A{}
X实现类需要重写ABC接口的所有方法,否则就是抽象类
class A extends B implements C,D{}
其中A是实现类,也是B的子类,同时拥有CD接口的所有功能
这时A需要重写CD接口里的所有抽象方法

4. 抽象类与接口的区别
1)抽象类是一个特殊的类,特殊在,抽象类中可以包含没有方法体的方法(抽象方法)

抽象类里成员变量、成员常量、构造方法、普通方法、抽象方法都可以有

抽象方法只能声明,不能实现,抽象类是向上抽取形成的结果,接口则是预先设计的结果
抽象类可以有构造方法–用来给子类创建对象,接口中没有构造方法
抽象类和接口都不能实例化(创建对象)
2)接口可以理解成一个特殊的抽象类,特殊在,接口里除了被static或者default修饰普通方法有方法体,其他的都是抽象方法,没有其他普通方法

接口里只能有静态常量和抽象方法
接口会为方法自动拼接public abstract,还会为变量自动拼接public final static
接口可继承接口,并可多继承接口,但类只能单继承

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值