黑马程序员 - 接口、内部类和异常

 

 

抽象类
特点:
1.方法只有声明没有实现时,该方法就是抽象类,需要用 abstract 修饰
2.抽象类不可以被实例化,因为调用抽象方法没意义
3.抽象类必须有其子类覆盖所用的抽象方法后,该子类才可以实例化,否则这个子类还是抽象类

1.抽象类中有构造函数么?
有,虽然抽象类不能用 new 创建对象,不需要初始化,但是可以用于给子类进行初始化。

2.抽象类可以不定义抽象方法么?
可以,但很少见,目的就是//不让该类创建对象。
通常这种类中的方法有方法体,但是没有内容。

例:void show()
{}

3.抽象关键字不可以和那些关键字共存?
private 不行,因为 private 修饰的内容不能被子类覆盖
static 不行,
final 不行,因为 final 修饰的内容不能被子类覆盖

4.抽象类和一般类的异同
相同:
均用来描述事物,在内部定义成员。
不同点:
1.一般类不能定义抽象方法
抽象类可以定义抽象及非抽象方法。
2.一般类可以被实例化
抽象类不可以被实例化

抽象类演示:

abstract class Damo
{
    abstract void show();  //抽象的函数
}

class DemoA extends Dame
{
    void show()          //如果子类继承抽象类狗没有覆写抽象方法,该子类仍然为抽象类
    {
        System.out.println("Hello DemoA");        
    }
}

class DemoB extends Demo
{
    void show()
    {
        System.out.println("Hello DemoB");
    }
}

抽象类的应用

雇员示例:
需求:公司程序员有姓名,工号,薪水,工作内容。
项目经理有。。。等,还有奖金。

分析:
想找出涉及的对象
程序员:
属性:姓名,工号,薪水
行为:工作
经理:
属性:姓名,工号,薪水,奖金
行为:工作
程序员与经理不存在直接继承关系,但是程序员与经理具有共性内容。
将程序员与经理进行抽取,建立体系

abstract class Employee     //定义雇员
{    
    private String name;    //定义成员变量
    private String id;
    private int payment;
    Employee(String name,String id,int payment)//定义成员构造函数
    {
        this.name = name ;
        this.id = id ;
        this.payment = payment ;
    }
    public abstract void work(); //定义抽象方法
}

//描述程序员
class Programmer extends Employee    //令程序员继承雇员
{
    Programmer(String name,String id,int payment)    //定义程序员的构造方法
    {
        super(name,id,payment);
    }
    void work()                             //此行覆盖父类中的抽象方法
    {
        System.out.println("code...");        //定义程序员的特有方法
    }
}
//描述项目经理
class Manager extends Employee        //令项目经理继承雇员
{
    private int bonus;                //定义成员变量
    Manager(String name,String id,int payment,int bonus)    //定义项目经理的构造函数
    {
        super(name,id,payment);        //继承父类构造函数
        this.bonus = bonus ;
    }
    void work()                        //覆盖父类抽象方法
    {
        System.out.println("manage...");    //定义项目经理特有方法
    }
}

当一个抽象内中的方法均为抽象时,可以将该抽象类用另一种形式定义和表示,就是接口 interface
此时,定义接口的关键字是 interface 而非 class
对于接口中的成员,均有固定的修饰符

1.全局常量 public static final (这些修饰符是固定的,即使没有写,程序也会自动添加。)

2.抽象方法 public abstract (这些修饰符是固定的,即使没有写,程序也会自动添加。)

由此可以看出,接口中成员都是公共权限。

interface InterfaceDemo
{
    public static final int num = 4 ;
    abstract void show1();
    abstract void show2();
}

类与类之间是继承关系,接口与接口之间是继承关系(而且可以多继承),类与接口之间是实现关系此时关键字用 implements 。
接口不可以被实例化,只能由实现了接口的子类并覆盖了接口中所有的抽象方法后,该子类才可以实现化。

class  DemoA implements InterfacceDemo  // implements A,B就是多实现
{
    void show1()
    {
        //具体的实际的方法略
    }
    void show2()
    {
        //具体的实际的方法略
    }
}

实现的好处是可以实现 多实现,一个类可以实现多个接口。
一个类在继承一个类的时候,还可以实现多个接口,接口的出现避免了单继承的局限性。
class Test extends C implements A,B

一个接口使用实例
笔记本电脑通过usb接口扩展u盘

interface USB                                  //暴露接口规则
{
    public void open();
    public void close();
    public void work();
}

class Upan implements USB                     //定义一个符合usb规则的upan
{
    public void open()
    {
        System.out.println("upan open");     //定义具体的实现方法
    }
    public void close()
    {
        System.out.println("upan close");
    }
    public void work()
    {
        System.out.println("upan work");
    }
}

class Laptop                                 
{
    public static void main(String[] args)
    {
        useUSB(new Upan());                 //创建一个upan,并通过定义的使用方法使用
    }
    public static void useUSB(USB u)        //定义一个使用usb的方法
    {
        u.open();
        u.close();
        u.work();
    }
}

运行结果:U盘正常运行

 

内部类的特点:
1.内部类可以直接访问外部类的成员。
2.外部类药访问内部类必须建立内部类的对象。
静态类中的成员,函数均为静态的。
内部类在局部位置在上只能访问局部中被final修饰的局部变量。

interface Demo
{
    void show();
}
class Outsider 
{
    private int num = 3 ;
    void method()//如无此行,内部类直接写在外部类中时,可用 Outsider.Intersider in2 = new Outsider().new Intersider(); //直接访问内部类中的内容,记格式。
    {
        final int a = 4 ;   //在内部类中访问局部变量时,必须在变量前加final
        class Intersider
        {
            int num = 5 ;
            void show()
            {
                System.out.println("num="+num);
                System.out.println("num="+Outsider.this.num);  //此时输出的是外部的num = 3. 仅内部类与外部类出现重名变量的时候才这样使用。
                System.out.println("a="+a);              //要访问a这局部变量,必须在变量前加 final
            }
        }
        Intersider in1 = new Intersider();
        in1.show();
        System.out.println();
    }
//以下为演示匿名内部类
    public void method0()
    {
        new Demo()  //此时Demo是抽象类,不能直接创建对象,但此时已经在其中具体了其抽象方法的具体实现,所以这步实际上是创建了一个Demo的子类的对象
        {                        //这种方法是创建了一个子类,所以可以在其中添加子类特有的方法,例如 show2()
            public void show()  //public 必须加上(重要)
            {
                System.out.println("匿名内部类01");
            }
        }.show();                      //.show()很重要,和普通一样,表示使用。

        Demo in = new Demo()           //这种方法创建的子类,自动向上转型成为了Demo类,所以不可以添加子类特有的方法,仅可以复写Demo中已有的方法。
        {
            public void show()         //public 必须加上(重要)
            {
                System.out.println("匿名内部类02");
            }
        };                            // ; 很重要
        in.show();
    }
}



class Neibulei
{
    public static void main(String[] args) 
    {
        Outsider Out = new Outsider();
        Out.method();
        new Outsider().method();                   //此方法为用匿名类
        new Outsider().method0();
    }
}

异常类

注意:如果让一个类成为异常类,必须继承异常体系,因为只有成为异常类才能被关键字 throws throw

异常的分类:
1:编译时被检测异常,主要是Exception 和 其子类(除 RuntimeException)
这种问题一旦出现,希望在编译时就进行检测,让这种问题有对应的处理方式
这种问题都可以针对性的处理。
2:编译时不检测异常(运行时异常):就是RuntimeException 及 其子类。
这种问题发生,无法让功能继续,大多是因为调用者的原因导致
这种问题一般不处理,直接编译通过,在运行时,让调用哪个最调用时的程序强制停止,让调用者对代码进行修正

异常处理的捕捉形式:
这是可以对异常进行针对性处理的方式。
具体格式:

try
{
    //需要被检测异常的代码
}
catch(异常类 变量)//该变量用于接收发生的异常对象
{
    //处理异常的代码。
}
finally    //通常用于关闭(释放)资源
{
    //一定会被执行的代码。
}

异常处理原则

1:函数内部如果抛出需要检测的异常,那么函数上必须要添加声明,或者必须在函数内用try catch捕捉,否则编译失败。
2:功能内容可以解决,用catch
解决不了,用throws告诉调用者,由调用者解决。
3:一个功能如果抛出 多个异常,那么调试时,必须有对应多个catch进行针对性的处理。
抛出几个,就catch几个。

异常应用演示

class Fushuindex extends RuntimeException    //继承的Exception时,需要throws Fushuindex (添加捕捉自定义声明)
{
    Fushuindex(String a)
    {
        super(a);                       //直接调用父类的方法
    }
}
class Demo
{
    public int method(int [] arr , int index) //继承的Exception时,需要throws Fushuindex (添加捕捉自定义声明)
    {
        if(arr==null)
            throw new NullPointerException("数组的角标不能为空");
        if(index >=arr.length)              //判断问题
            throw new ArrayIndexOutOfBoundsException("数组角标越界了: "+index);   //自定义异常返回信息
        else if(index < 0)
            throw new Fushuindex("数组角标不能小于0: ");
        else
            return arr[index];
    }
}
class  ExceptionDemo
{
    public static void main(String[] args)  //继承的Exception时,需要throws Fushuindex (添加捕捉自定义声明)
    {
        int [] a = new int [3];
        Demo d = new Demo();
        int num1 = d.method(a,1);
        System.out.println("Hello World!"+num1);
//以下演示异常捕捉
//多catch 时,父类catch必须放在最下面
        try
        {
            int num2 = d.method(a,-30);
            System.out.println("num2 = "+num2);
        }
        catch (Fushuindex x)
        {
            System.out.println("负数角标异常");
            System.out.println(x.toString());  //异常信息
        }
        catch (Exception e)
        {}
            System.out.println("over");
    }
}

 

posted @ 2015-08-21 19:07  koibiki  阅读(200)  评论(0编辑  收藏  举报