Java基础视频教程第09天_面向对象之内部类、异常1

来源:互联网 发布:nginx tomcat负载均衡 编辑:程序博客网 时间:2024/06/06 03:56

一、面向对象——内部类访问规则

1、内部类概念:将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类、嵌套类)。2、访问特点:A、内部类可以直接访问外部类中的成员,包括私有成员;(之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式是:外部类名.this.)B、外部类要访问内部类中的成员必须要建立内部类的对象。3、外部其他类访问格式:当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中直接建立内部类对象。格式:外部类名.内部类名 变量名 = 外部类对象.内部类对象。例如: Outer.Inner in = new Outer().new Inner();4、注意:内部类可以被 private 修饰,因为内部类是外部类的成员。此时,将内部类封装在外部类中。示例:
class InnerClassDemo{public static void main(String[] args) {//调用内部类的方式一:Outer out = new Outer();out.method();//调用内部类的方式二:Outer.Inner in = new Outer().new Inner();in.function();//调用内部类的方式三:new Outer().new Inner().function();}}class Outer{private int x = 3;//private class Inner //内部类可以被私有class Inner{int x = 4;void function(){int x = 6;System.out.println("inner:x1="+x);//打印6System.out.println("inner:x2="+this.x);//打印4System.out.println("inner:x3="+Outer.this.x);//打印3}}void method(){Inner in = new Inner();in.function();}}

二、面向对象——静态内部类 

1、概念:
内部类是外部类的成员时,可以被 static 修饰,此时内部类就是静态内部类。

2、特点:
内部类被 static 修饰后,就具备 static 的特性,只能直接访问外部类中的 static 成员。出现了访问局限。

3、访问规则:
A、在外部其他类中,直接访问 static 内部类中的非静态成员的方式:
new Outer.Inner().function();


B、在外部其他类中,直接访问 static 内部类中的静态成员的方式:
Outer.Inner.function();

4、注意:
A、当内部类中定义了静态成员,该内部类必须是 static 的。
B、当外部类中的静态方法访问内部类时,内部类也必须是 static 的。

示例:
class InnerClassDemo{public static void main(String[] args) {Outer.Inner in = new Outer.Inner();//创建静态内部类规则;in.function();//new Outer.Inner().function();//当内部类静态时,访问内部类非静态方法的格式;Outer.Inner.function();//当内部类方法静态时,可直接访问;}}class Outer{private static int x = 3;static class Inner{ //当内部类中定义了静态成员,该内部类必须是静态的static void function(){System.out.println("inner:x="+x);//x相当于out.x }}public static void method(){new Inner().function();}}

三、面向对象——内部类定义原则

1、什么时候定义内部类?
当描述事物时,事物的内部还有事物,该事物用内部类来描述。因为内部事物在使用外部事物的内容。

示例:
class Body{private class Heart{}public Heart show(){return new Heart();}}

四、面向对象——局部/匿名内部类

(1)局部内部类:
1、内部类不仅可以定义在外部类成员位置上,也可以定义在局部位置上。
补充:一般内部类不会被 public 修饰,内部接口除外。

2、局部内部类的特点:
A、可以直接访问外部类中的成员,因为还持有外部类中的引用;
B、局部内部类不可以被 private 和 static 修饰;
C、局部内部类中的内部成员也不可以被 private 和 static 修饰;
D、局部内部类只能访问被 final 修饰的局部变量;
示例:
class InnerClassDemo3{public static void main(String[] args) {Outer out = new Outer();out.method(5);out.method(6);}}class Outer{int x = 3;void method(final int z){final int NUM = 4;class Inner{void function(){//z++;//z 被final修饰,不能重新赋值。System.out.println("x="+x);System.out.println("NUM="+NUM);System.out.println("z="+z);}}new Inner().function();//建立对象提供访问}}

(2)匿名内部类:
1、匿名内部类是内部类的简写格式。

2、定义匿名内部类的前提:
内部类必须是继承一个类或者实现接口。

3、匿名内部类的格式:
new 父类或者接口(){定义子类内容,复写父类方法};

4、其实匿名内部类就是一个匿名子类对象,这个对象有具体内容。

5、匿名内部类中定义的方法一般不超过3个。

示例:
class InnerClassDemo4{public static void main(String[] args) {Outer out = new Outer();out.function();}}abstract class AbsDemo{abstract void method();}class Outer{int x = 4;public void function(){AbsDemo d = new AbsDemo(){final int num = 9;void method(){System.out.println("x="+x);//x=4System.out.println("num="+num);//num=9}void show(){System.out.println("haha");}};d.method();//d.show();//编译失败,因为父类中没有show方法//但是可以按如下方法调用new AbsDemo(){void method(){System.out.println("method");}void show(){System.out.println("show");}}.show();}}

(3)练习一:根据以下代码补足Test类中的代码
/*class InnerClassTest{public static void main(String[] args){Test.function().method();}}interface Tnter{public abstract void method();}class Test{//补足代码}*/class  InnerClassTest{public static void main(String[] args) {Test.function().method();//Test.function(): Test类中有一个静态的方法function;//.method(): function这个方法运算后的结果的一个对象,而且是一个Inter类型的对象,该对象用来调用method();}}interface Inter{public abstract void method();}class Test{/*//方法一:非匿名,内部类static class Inner implements Inter{public void method(){System.out.println("method run");}}static Inter function(){return new Inner();}*///方法二:匿名内部类static Inter function(){return new Inter(){public void method(){System.out.println("method run");}};}}

(4)练习二: 什么时候使用匿名内部类?例如:
interface Inter{void method();}class InnerClassTest2 {public static void main(String[] args) {//调用show方法时使用匿名内部类的方式show(new Inter(){public void method(){System.out.println("method show run");}});}public static void show(Inter in){in.method();}}

(5)面试题:
class InnerTest{public static void main(String[] args){new Object()//Object obj = new Object(){public void function(){}}.function();//OK,子类直接调用//obj.function();//编译失败,因为父类中没有function方法。}}

五、面向对象——异常概述

1、异常体系
Throwable
Error
通常出现重大问题:如运行的类不存在或者内存溢出等;
不编写针对代码对其处理。
Exception
在运行时出现的情况,可以通过 try  catch  finally 

2、 Exception 和 Error 的子类名都是以父类名作为后缀。

3、理解:
异常:就是程序在运行时出现不正常情况。

异常由来:问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述。并封装成对象。异常其实就是java对不正常情况进行描述后的对象体现。

对于问题的划分:两种:一种是严重的问题,一种非严重的问题。
对于严重的,java通过 Error 类进行描述。对于 Error 一般不编写针对性的代码对其进行处理。
对与非严重的,java通过 Exception 类进行描述。对于 Exception 可以使用针对性的处理方式进行处理。

无论 Error 或者 Exception 都具有一些共性内容。比如:不正常情况的信息,引发原因等。所以可以对其进行抽取出一个父类。

六、面向对象——异常 try - catch 

1、异常处理:
java 提供了特有的语句处理异常:
try
{
需要被检测的代码;
}
catch ()
{
处理方式;
}
finally
{
一定会执行的语句;
}

2、常见的异常处理方法:
class Demo{public int div(int a, int b){return a/b; //new ArithmeticException()}}class ExceptionDemo{public static void main(String[] args) {Demo d = new Demo();try{int x = d.div(4,0);//new ArithmeticException()System.out.println("x="+x);}catch (Exception e)//Exception e = new ArithmeticException(){System.out.println(e.getMessage()); //  / by zeroSystem.out.println(e.toString());// 异常名称: 异常信息e.printStackTrace();// 异常名称: 异常信息;异常出现的位置。//JVM默认异常处理方式。}System.out.println("over");}}

3、对捕获到的异常对象进行常见方法操作: 
String getMessage(); 
String toString(); 
printStackTrace(); 

注意:
在输出语句中可以不用写 toString()方法,因为会自动调用。

七、面向对象——异常声明

1、如果程序运行过程中, try 中的代码不出现问题,则 catch 中的代码不会执行,而是继续向下运行。

2、在编写一个功能时,如果该功能有可能会出现异常;那么就必须在该功能上做一个标示,并通过 throws 关键字声明出该异常,以便调用者在调用该功能时知道该功能可能会出现的异常。

3、调用者对于接收到声明了有可能出现问题的程序时,就需要通过 try catch 处理,或者继续抛出。否则编译失败。
class Demo{int div(int a, int b)throws Exception //在功能上通过throws关键字声明了该功能有可能出现问题{return a/b;}}class ExceptionDemo2{public static void main(String[] args) //throws Exception //或者继续抛出异常{Demo d = new Demo();try //抛出异常时,尝试运行{int x = d.div(4,0);System.out.println("x="+x);}catch (Exception e) //异常处理方式{System.out.println(e.toString());}System.out.println("over");}}

八、面向对象——多异常处理

1、声明异常时,建议声明更为具体的异常,这样可以处理得更具体。

2、处理原则:
A、对方声明几个异常,就对应有几个 catch 块进行针对性处理;不要定义多余的 catch 块。
B、如果多个 catch 块中的异常出现继承关系,父类异常 catch 块放在最下面。

3、在进行 catch 处理时, catch 中一定要定义具体的处理方式;不要定义简单的输出信息。
class Demo{int div(int a, int b)throws ArithmeticException , ArrayIndexOutOfBoundsException{int[] arr = new int[a];System.out.println(arr[4]);return a/b;}}class ExceptionDemo3{public static void main(String[] args) {Demo d = new Demo();try{int x = d.div(4,0);System.out.println("x="+x);}catch (ArithmeticException e){System.out.println(e.toString());}catch (ArrayIndexOutOfBoundsException e){System.out.println(e.toString());}/*catch (Exception e){System.out.println(e.toString());}*/System.out.println("over");}}

九、面向对象——自定义异常

1、由来:
项目中会出现特有的问题,而这些问题并未被java所描述并封装成对象。所以对于这些特有问题,可以按照java对问题封装的思想,将特有的问题进行自定义的异常封装。

2、当在函数内部出现了 throw 抛出异常对象,那么就必须要给对应的处理动作。
要么在内部 try  catch 处理。
要么在函数上声明让调用者处理。
一般情况下,函数内出现异常,函数上需要声明。 RuntimeException 除外。

3、如何定义异常信息呢?
因为父类中已经把异常信息的操作都完成了。
所以子类只要在构造时,将异常信息传递给父类通过 super 语句。
那么就可以直接通过 getMessage() 方法获取自定义的异常信息。

4、自定义异常,必须是自定义类继承 Exception 。

5、继承 Exception 的原因:
异常体系有一个特点:因为异常类和异常对象都被抛出。他们都具备可抛性。
这个可抛性是 Throwable 这个体系中独有特点。只有这个体系中的类和对象才可以被 throws 和 throw 操作。

====== java定义好的异常可以自动创建异常对象抛出,自定义异常需要手动创建异常对象并抛出。 
====== 在编译时,先报告的是语法错误,异常问题最后报告。
class FuShuException extends Exception{//private String msg;private int value;FuShuException(String msg, int value){super(msg);//this.msg = msg;this.value = value;}public int getValue(){return value; }/*public String getMessage(){return msg;}*/}class Demo{int div(int a, int b)throws FuShuException //函数内出现异常,函数上需要声明{if (b<0){throw new FuShuException("/ by minus", b);//手动通过throw关键字抛出一个自定义异常对象。同时让程序跳转。}return a/b;}}class ExceptionDemo4{public static void main(String[] args) {Demo d = new Demo();try{int x = d.div(4,-2);System.out.println("x="+x);}catch (FuShuException e){System.out.println(e.toString());System.out.println("除数: "+e.getValue());}System.out.println("over"); }}

Throwable 以及 Exception 对message的定义思想体现:
class Throwable {private String message;Throwable(String message){this.message = message;}public String getMessage(){return message;}}class Exception extends Throwable{Exception(String message){super(message);}}

十、面向对象—— throw 和 throws 的区别

throws 和 throw 的区别:
throws 使用在函数上。
throw 使用在函数内。

throws 面跟的是异常类;可以跟多个。用逗号隔开。
throw 后跟的是异常对象。

十一、面向对象—— RuntimeException 

1、 Exception 中有一个特殊的子类异常 RuntimeException 运行时异常。

2、 RuntimeException 异常的特点:
A、如果在函数内容抛出该异常,函数上可以不用声明,编译一样通过。
B、如果在函数上声明了该异常。调用者可以不用进行处理。编译一样通过;
原因:之所以不用在函数声明,是因为不需要让调用者处理。而应该在该异常发生时,希望程序停止。
因为在运行时,出现了无法继续运算的情况,希望停止程序后,对代码进行修正。

3、自定义异常时:如果该异常的发生,无法在继续进行运算,就让自定义异常继承 RuntimeException 。

4、对于异常分两种:
A,编译时被检测的异常。
B,编译时不被检测的异常(运行时异常: RuntimeException 及其子类)

5、 RuntimeException 子类举例:
RuntimeException
-ArithmeticException  
-NullPointerException  
-IndexOutOfBoundsException  
-ArrayIndexOutOfBoundsException  
-StringIndexOutOfBoundsException

代码一:
class FuShuException extends RuntimeException //希望发生该异常时,让程序停止{FuShuException(String msg){super(msg);}}class Demo{int div(int a, int b) //throws FuShuException, ArithmeticException 函数内抛出,函数上可以不用抛出{if(b<0)throw new FuShuException("//by minus");if(b==0)throw new ArithmeticException("by zore ---");return a/b;}}class ExceptionDemo5{public static void main(String[] args) //throws FuShuException, ArithmeticException 接收了可能存在问题的该异常,可以不用处理{Demo d = new Demo();int x = d.div(4,0);System.out.println("x="+x);System.out.println("over");}}

NullPointerException 举例:
class Person{private String name;Person(String name){this.name = name;}public boolean checkName(String name){//if(name.equals("lisi"))//当传入null时,会发生NullPointerException if("lisi".equals(name))//修改技巧//if(name!=null && name.equals("lisi"))return true;elsereturn false;}}class Demo{public static void main(String[] args){Person p = new Person("lisi");boolean bl1 = p.checkName(null);System.out.println(bl1);boolean bl2 = p.checkName("lisi");System.out.println(bl2);}}

十二、面向对象——异常练习

需求:
毕老师用电脑上课。
分析:
名词提炼法。

思考上课时,可能出现的异常:
电脑问题:
电脑蓝屏;
电脑冒烟

当冒烟发生后,出现讲课进度无法继续;就出现了新问题——课时计划无法完成。
代码:
class BlueException extends Exception{ //定义异常类,该异常可处理BlueException(String message){super(message);}}class MaoYanException extends Exception { //定义异常类,该异常不可以处理MaoYanException(String message){super(message);}}class NoPlanException extends Exception{NoPlanException(String message){super(message);}}class Computer{private int state = 1;//1代表正常,2代表蓝屏,3代表冒烟public void run(int num)throws BlueException,MaoYanException{state = num;if(state==1)System.out.println("computer run");else if(state==2)throw new BlueException("电脑蓝屏");else if(state==3)throw new MaoYanException("电脑冒烟");elseSystem.out.println("传入非法值");}//重启电脑public void reset(){state = 1;System.out.println("computer reset");}}class Teacher{private String name;private Computer cmpt;Teacher(String name){this.name = name;cmpt = new Computer();}public void prelect()throws NoPlanException{try{//设置电脑运行时可能出现的各种状况cmpt.run(3);}catch (BlueException e){System.out.println(e.getMessage());cmpt.reset();}catch (MaoYanException e){System.out.println(e.getMessage());test();throw new NoPlanException("no plan: "+e.getMessage());}System.out.println(name+": prelect");}public void test(){System.out.println("test");}}class ExceptionTest{public static void main(String[] args) {Teacher t = new Teacher("bilaoshi");try{t.prelect();}catch (NoPlanException e){System.out.println(e.toString());System.out.println("放假");}}}

注意:
throw 单独存在时,下面不可以写语句, throw 是函数的结束标示,它一结束,下面的语句执行不到。
0 0