黑马程序员---java学习笔记之面向对象:静态内部类

来源:互联网 发布:数学必修三算法 编辑:程序博客网 时间:2024/06/05 12:07
------- android培训、java培训、期待与您交流! ----------


1、内部类在外部类的成员位置上时,就可以用修饰类成员的修饰符修饰该内部类

        a):private修饰内部类,该类就被封装,不能被外部其他类直接访问;

        b):static修饰内部类,并且该内部类未被私有,那么访问该内部类中的非静态方法就可以采用这样的格式:new 外部类名.内部类名().内部类中的非静态某函数名

访问该内部类中的静态方法的格式为:外部类名.内部类名.内部类中的某静态函数。另外,非静态的内部类中不允许出现静态成员。也可以这么说,当内部类中定义了静态成员,该内部类就一定要用static修饰

2、当外部类中静态方法可以访问内部类中的方法时,该内部类也必须是静态的。

3、当内部类定义在局部位置上时的一些注意事项,通过代码体现:

public class InnerDemo {public static void main(String[] args) {new Outer().method(7);}}class Outer{int x = 4;public void method(final int a){class Inner{void function(){//定义在局部位置上的内部类可以调用外部类的成员,包括私有的System.out.println("Inner:"+x);show();//调用该内部类局部位置上的局部变量时,该局部变量应该设为finalSystem.out.println("局部变量:"+a);}}new Inner().function();//该语句写在内部类Inner之前是不对的}private void show(){System.out.println("Hello World!");}}
将文字提取出来就是:

        a):定义在局部位置上的内部类可以调用外部类的成员,包括私有的;

        b):调用该内部类局部位置上的局部变量时,该局部变量应该设为final;

4、说一个final修饰的局部变量的问题

public class FinalTest {public static void main(String[] args) {// TODO Auto-generated method stubA a = new A();a.methodA(5);a.methodA(6);}}class A{public void methodA(final int a){System.out.println(a);}}
分析:局部变量a是由final修饰的,程序可以每调用一次final就可以给a赋值一次,但是a由final修饰应该只能赋值一次呀,为什么程序中赋值了好多次,还能正常运行?解答是:每次调用methodA方法就会在栈中开辟一个methodA的空间用来存储该方法中的变量,此时a被分得空间,之后运行完该方法后,这部分栈空间就被释放,当然a的空间也释放,从a被分配空间到空间被释放,都只被赋值一次,是符合final修饰的要求的,再次调用时,又重复此过程。

5、匿名内部类:

        a):定义一个匿名内部类的前提是该内部类必须继承或者实现了一个接口;

        b):匿名内部类定义的格式:new 内部类继承的类或接口().{  实现的方法  };

        c):匿名内部类中的方法最好不要超过3个;

        d):匿名内部类使用的两种情况:某函数的形参是抽象类型或者接口类型时,此时可以使用匿名内部类之间在该函数被调用时的实参列表里创建匿名内部类对象;只有一个方法要被使用,没有明显的要继承类和要实现的接口,此时可以采用这种格式:

        new Object(){要被使用的方法}.要被使用的方法名

6、异常

        a):概念:程序在运行时出现的不正常情况。java中的异常是java语言对生活中不正常事物描述的对象体现。

        b):对于问题分为两类:严重与分严重的。在java语言中,严重的就用Error描述,非严重的就用Exception描述。

        c):Throwable

                   |----Error

                   |---Exception

        d):Throwable的三个方法:getMessage(),toString()以及printStackTrace();

        e):java已定义的异常,可以自动抛出,而我们自定义的异常就需要我们手动抛出;

        f):异常分为两种:编译时被检测异常;编译时不被检测异常(也就是RuntimeException及其子类)

        g):try{……被检测是否有异常的语句……}catch{……异常处理语句……}finally{……不管有没有异常都一定会执行的语句……}

7、try语句的几种组合形式:

        a):try{}  catch{};

        b):try{} catch{} finally{};

        c):try{} finally{}; 

8、函数的覆盖在异常中应用:

        a):子类的方法覆盖父类的方法,子类的该方法抛出的异常只能是父类抛出的异常或其子异常,或者不抛异常;

class AException extends Exception{}class BException extends AException{}class CException extends Exception{}class Fu{void show() throws AException {}}class DDemo{public void Demo(Fu f){try{f.show();}catch(AException e){}}}class Zi extends Fu{void show() throws CException{}}public class ExceptionDemo {public static void main(String[] args) {new DDemo().Demo(new Fu());new DDemo().Demo(new Zi());}}
由于子类覆盖的show方法抛出的是CException(与BException在继承体系上属于同级),所以导致DDemo类中Demo方法在接受子类对象Zi时的catch语句不能够处理该异常!

        b):如果子类抛出多个异常,那么子类覆盖方法只能抛出父类抛出异常(或其子异常)的子集;

        c):如果父类或者接口方法没有抛出异常,那么子类的覆盖方法就不能抛出异常,即便在子类方法中会出现异常,那么也只能在在内部处理。

9、异常的知识点总结

        a):异常的概念:异常是对问题的描述,将问题进行对象的封装;

        b):异常体系:

Throwable

        |---Error

        |---Exception

                |---RuntimeException

        c):异常体系的特点:异常体系中的所有类以及建立的对象都具有可抛性,也就是说可以被throws或者throw操作,只有异常体系具备这个特点

        d):throw和throws的用法:throw定义在函数内用于抛出异常对象;throws定义在函数上,用于抛出异常类,可以抛出多个异常类,之间用逗号隔开;当函数内有throw抛出异常对象,并且在函数内并未对其进行try处理,就必须在函数声明抛出异常,否则编译不通过。RuntimeException异常除外,也就是说 函数内抛出了RuntimeException或者其子类的异常,函数上可以不声明。

如果函数声明了异常,调用者需要对其进行处理,处理的方式可throws可try。

        e):异常有两种:编译时被检测异常(该异常在编译时如果没有处理,没throws也没try,编译失败;该异常被标示,说明可以被处理);运行时异常(编译时不检测异常,编译时不需要处理编译器不检查;该异常发生时,建议不处理让程序停止。需要对代码进行修正)。

        f):异常处理语句:try{……需要被检测异常的代码……}catch{……处理异常的代码……}finally{……一定会执行的代码……}

有三种组合方式:try{}catch{};try{}catch{}finally{};try{}finally{}

finally中定义的通常是关闭资源代码 ,因为资源必须被关闭;finally只有一种情况不会被执行,当执行到System.exit(0)时,finally不会执行

        g):自定义异常:定义继承自Exception或者RuntimeException的子类;

这样做一是为了让该自定义类具备可抛性;二是为了让该类具备操作异常的共性方法。

当要定义自定义异常的信息时,可以使用父类已定义好的功能,异常信息传递给父类的构造函数;

class MyException extends Exception{        MyException(String message)        {                super(message);        }}
自定义异常就是按照java面向对象的思想,将程序中出现的特有问题进行封装。

        h):异常的好处:将问题进行封装;将正常阅读代码和问题处理代码相分离,方便于阅读

        i):异常的处理原则:处理方式有两种,throws和try;调用到抛出异常的功能时,抛出几个就处理几个(一个try对应多个catch);多个catch,父类的catch放到最下面;catch代码段里需要定义针对性的处理方式,不要简单调用printStackTrace,也不能写简单的输出语句,也不能什么也不写;当捕获的异常本功能函数并不能处理时,可以继续在catch中抛出。

如果某异常处理不了,且并不属于该功能出现的异常,可以将异常转换后,在抛出可该功能相关的异常;

或者异常可以处理,当需要将异常产生的和本功能相关的问题提供出去,让调用者知道并处理,也可以将捕获异常处理后,转换新的异常。

try{        throw new AException();}catch( AException e ){//对AException先进行处理 throw new BException();}
        j):异常的注意事项:在子父类方法覆盖时,子类覆盖方法的异常必须是父类被覆盖方法异常的子类或者子集,如果父类或者接口的某方法没有抛出异常,那么子类覆盖方法时也不能够抛出异常(如果子类方法中确实可能会有以藏抛出,那就必须在该方法中处理而不能抛出)。

10、个人认为非常好的例题:

interface Test{void show();}class Demo1{public static void main(String[] args){//问题:使用匿名内部类调用show方法/*首先,不能在主函数中直接这样写:show(...),因为主函数是静态的,不能调用非静态方法 * 所以应该先创建Demo1的对象,然后在调用show方法 * 接下来就是匿名内部类的部分了 * */new Demo1().show(new Test(){public void show(){}});}void show(Test t){}}

下面是一道经典的java面试题目:

public class Test1 {/** * 这是一道相当经典的java面试题,仔细分析,你就会得到正确的结果。 */public static String output = "";public static void foo(int i){try{if( i == 1 )throw new Exception();output += "1";}catch(Exception e){output += "2";return ;}finally{output += "3";}output += "4";}public static void main(String[] args) {foo(0);System.out.println(output);//打印结果是:"134"foo(1);System.out.println(output);//打印结果是:"13423"}}

11、包

        a):关键字是package,package语句应放在代码文件第一行;包名全都是小写;

        b):包里面的类文件的全称是“包名.类名”

         c):命令“javac -d 指定目录 java源文件”意思是将指定源文件编译并把编译所得类文件存储在指定目录下,指定目录的位置如果是“.”,表示当前目录;如果你想在任意目录下都能执行在某目录下的类文件,你可以尝试在dos中使用“set class=类文件所在目录”的形式设置。

        d):一个包访问另一个包中的类及其方法,被访问的包中的该类和该方法需要被public修饰;一个包中的类,其子类在另一包中,该子类可以访问到该父类中由protected修饰的成员

 12、导入包的关键字是import,导包时需注意的是导入的只是包目录下的类文件,而没有导入子包。另外当导入的包与包之间或者当前包与导入包之间的类有重名的情况时,导入包的重名类在使用时就必须加上包名。

13、使用包的好处:

        a):方便于对工程文件的管理;

        b):有效避免类重名

14、dos命令行中的数据重定向符号“>”,查看jre里的lib目录下的rt.jar示例。

15、java的工具是用java写成的,相关使用其实是在执行相关的类文件,所以jdk里面一定要有一个jre。

16、java是开源的,可以查看源代码

0 0