• 黑马程序员——java学习5(107-126)——内部类,异常,包


    1、内部类

    1.1何时:

    事物的内部还有事物,就用内部类(人体和心脏举例)

    方法:

    (1)内部类可以直接访问外部类中的成员,包括私有。

      之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式:外部类名.this

    (2)外部类要访问内部类,必须建立内部类对象

    格式:

    (1)当内部类定义在外部类的成员位置上,且非私有,可以在外部其他类中,可以直接创建内部类对象

    Outer.Inner out=new Outer().new Inner();

    (2)当内部类在成员位置上时,就可以被成员内部类修饰符所修饰。

    private,static等,当内部类被静态修饰后,只能访问外部类中的static成员

    当内部类中定义了静态成员,该类必须是静态

    当外部类中的静态方法访问内部类时,内部类必须为静态。(静态不建实例已存在)

    面试:

    在外部其他类,如何访问static内部类的非静态成员?

    new Outer.Inner().function();

    在外部其他类,如何访问static内部类的静态成员

    Outer.Inner.function();

     1 package learn;
     2 class Outer{
     3 private int x=3;
     4 class Inner{//内部类
     5 int x=4;
     6 void function(){
     7 int x=5;
     8 System.out.println("inner"+x);
     9 System.out.println("inner"+this.x);
    10 System.out.println("inner"+Outer.this.x);
    11 }
    12 }
    13 void method(){
    14 Inner in=new Inner();
    15 in.function();
    16 }
    17 }
    18 public class InnerClassDemo {
    19 public static void main(String[] args) {
    20 Outer out=new Outer();
    21 out.method();
    22 //内部类非私有时可如下访问
    23 Outer.Inner Inn=new Outer().new Inner();
    24 Inn.function();
    25 }
    26 }

    1.2.内部类定义在局部时

    不可以被成员修饰符修饰(static)

    (1)可以直接访问外部类中的成员,因为还持有外部类中的引用

    package learn;
    
    class Outer{
        int x=3;
        void method(){
            class Inner{
                void function(){
                    //内部类调用外部类的成员变量
                    System.out.println(Outer.this.x);
                }
            }
            //非静态类,没对象不运行
            new Inner().function();
        }
    }
    public class InnerClassDemo3 {
        public static void main(String[] args) {
            new Outer().method();
        }
    }

    (2)但是不可访问他所在的局部中的变量,只能访问被final修饰的局部变量

     1 package learn;
     2 
     3 class Outer3{
     4     int x=3;
     5     void method(){
     6         final int y=4;
     7         class Inner{
     8             void function(){
     9                 //内部类访问它所在的局部中的变量,必须为final
    10                 System.out.println(y);
    11             }
    12         }
    13         //非静态类,没对象不运行
    14         new Inner().function();
    15     }
    16 }
    17 public class InnerClassDemo3 {
    18     public static void main(String[] args) {
    19         new Outer3().method();
    20     }
    21 }

    1.3、匿名内部类

    就是内部类的简写

    前提:内部类必须继承一个类或者实现一个接口

    何时:使用过的方法的参数是匿名内部类,且其中方法不超过3个

    如:public static void show(Inner in)可换成如下:

    show(new Inter

    {

      public void method(){

        System.out.println("method show run");

    }

    });

    格式:new父类/接口(){定义子类的内容}

    其实匿名内部类就是匿名子类对象,可以理解为带内容的对象

    匿名对象调用方法只可调用一次,且不可调用自己的方法,最好别超过3个

     1 package learn;
     2 
     3 abstract class AbsDemo{
     4     abstract void show();
     5 }
     6 
     7 class Outer4{
     8     int x=3;
     9 //    class Inner4 extends AbsDemo{
    10 //        void show(){
    11 //            System.out.println("show"+x);
    12 //        }
    13 //    }
    14 //    public void function(){
    15 //        new Inner4().show();
    16 //    }
    17 //    
    18     public void function2(){
    19     //AbsDemo d=new AbsDemo()也可以
    20     new AbsDemo(){
    21         void show(){
    22             System.out.println("show"+x);
    23         }
    24             
    25     }.show();
    26     
    27     }
    28 }
    29     
    30 public class InnerClassDemo4 {
    31     public static void main(String[] args) {
    32 //        new Outer4().function();
    33         new Outer4().function2();
    34     }
    35 }
     1 package learn;
     2 interface Inter{
     3     void method();
     4 } 
     5 class Test{
     6     static class Inner implements Inter{
     7         public void method(){
     8             System.out.println("1");
     9         }
    10     }
    11     static Inter function(){
    12 //        return new Inner();//内部类
    13         //匿名内部类
    14         return new Inter(){
    15             public void method(){
    16                 System.out.println("1");
    17             }
    18     };
    19 }
    20 }
    21 public class InnerClassDemo5 {
    22     public static void main(String[] args) {
    23         //倒推
    24         Test.function().method();
    25         //Test类中有个静态方法function,
    26         //.method:function方法运算后的结果是一个对象,而且是一个Inner类型的对象
    27         //因为只有Inner类型的对象,才可以调用method方法
    28     }
    29     
    30 }

    2、异常

    异常也是一类对象,表示现实生活中的具体的事物

    问题分为严重和非严重

    严重的是Error类

    error不编写针对性的代码对其进行处理

    非严重的是Exception类描述

    编写针对性的代码

    好处:

    (1)将问题进行封装

    (2)将正确流程代码和问题代码相分离,便于阅读

    2.1处理过程:

    try{

      需要被检测的代码

    }

    catch(异常类 变量){

      处理异常的代码

    }

    finally{

      一定会执行的语句

    }

    对捕获到的异常对象的常见方法操作

     1 package learn;
     2 class Demo{
     3     int div(int a,int b)
     4     {
     5         return a/b;
     6     }
     7 }
     8 
     9 public class ExceptionDemo {
    10 public static void main(String[] args) {
    11     Demo d=new Demo();
    12     try
    13     {
    14         int x=d.div(4, 0);   //new Exception()
    15         System.out.println("x="+x);
    16     }
    17     catch(Exception e)//Exception e=new Exception()
    18     {
    19         System.out.println("除零了");
    20         System.out.println(e.getMessage());//  /byzero详细消息的字符串
    21         System.out.println(e.toString());//异常名称:异常信息
    22         e.printStackTrace();//打印堆栈中的跟踪信息,异常名称,异常信息,异常出现的位置
    23         //其实jvm默认的异常处理机制就是在调用printStackTrace方法
    24     }
    25 }
    26 }

    2.2、异常声明方法,throws Exception

    一开始声明,告诉这里可能会出错,便于提高安全性,让调用出进行处理,不处理编译失败。内部解决了(有catch)可以不声明

    1 class Demo{
    2     int div(int a,int b)throws Exception//在功能上通过throws关键字声明了该功能可能出现问题
    3     {
    4         return a/b;
    5     }
    6 }

    2.3、多异常处理

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

    (2)、对方声明几个异常,对应有几个catch块

    如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面(不然它会解决所有能解决的问题,使问题笼统为一个名字)

    (3)、一定要定义具体处理方式,别定义e.printStackTrace();也别书写一条输出语句

    2.4、自定义异常

    为了显示出异常信息,自定义类继承Exception,因为父类中把异常信息的操作都完成了,所以子类在构造时,将传递给父类通过super语句。

    就可以直接通过父类的getMessage方法获取自定义的异常信息了。

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

     1 package learn;
     2 class FuShuException extends Exception{
     3     private int value;
     4     FuShuException(){
     5         super();
     6     }
     7     FuShuException(String msg,int value){
     8         super(msg);
     9         this.value=value;
    10     }
    11     public int getValue(){
    12         return value;
    13     }
    14 }
    15 class Demo3{
    16     int div(int a,int b)throws Exception{//函数上
    17         if(b<0)
    18             //函数内
    19             throw new FuShuException("出现了除数是负数的情况,",b);//手动通过throw关键字抛出一个自定义异常
    20         return a/b;
    21     }
    22 }
    23 
    24 class ExceptionDemo3{
    25     public static void main(String[] args){
    26         Demo3 d=new Demo3();
    27         try
    28         {
    29             int x=d.div(4, -1);   
    30             System.out.println("x="+x);
    31         }
    32         catch(Exception e)
    33         {
    34             System.out.println(e.toString());
    35             System.out.println("除数变负数");
    36         }
    37         System.out.println("over");
    38     }
    39 }
    40 
    41 //// 1,2推出3,
    42 //class Throwable{
    43 //    private String message;           //3
    44 //    Throwable(String message)
    45 //    {
    46 //        this.message=message;         //2
    47 //    }
    48 //    public String getMessage(){
    49 //        return message;               //1
    50 //    }
    51 //}
    52 //
    53 //class Exception extends Throwable{
    54 //    Exception(String message)
    55 //    {
    56 //        super(message);
    57 //    }
    58 //}

    2.5、throws和throw

    throws使用在函数,后面跟的异常类。可以跟多个。用逗号隔开    //int div(int a,int b)throws FuShuException{

    throw使用在函数,后面跟的是异常对象

    2.6、特殊的异常RuntimeException

    函数内抛出异常,函数上不用声明

    函数上声明异常,调用者可以不处理

    因为希望程序停止,被修改,问题不被隐藏

    自定义异常时,如果该异常发生,无法再继续进行运算,就让自定义异常继承RuntimeException

    总结:

    异常分两种

    (1)、编译时被检测的异常,必须声明

    (2)、编译时不被检测的异常(运行时异常,RuntimeException以及其子类)

    2.7、finally

    执行一定要做的动作,一般用于关闭资源

    try+catch(可多个catch); try+catch+finally; try+finally

    只有当系统执行到System.exit(0);finally才不会执行

    2.8、异常在子父类覆盖中的表现:

    (1)子类在覆盖父类时,如果父类抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者异常的子类

    (2)如果父类方法抛出多个异常,那么在子类覆盖该方法时,只能抛出父类异常的子集。

    (3)如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常

      如果子类方法发生了异常,就必须要进行try处理,绝对不能抛

    PS:视频123练习四※

    3、包

    封装的体现

    让java和class文件分离存放

    javac -d . PackageDemo.java//在当前路径下创建包并把class文件放进去

    set classpath=包的父目录,不需进入包

    3.1、包与包之间

    类,被访问的成员,都要public

    不同包中子类,还可以访问父类中被protected权限修饰的成员

    包与包之间可以使用的权限:

          public> protected> default> private

    同一个类中  ok    ok    ok    ok

    同一个包中  ok    ok    ok    

    子类     ok    ok    

    不同包中   ok

    一个java文件中不能出现两个以上的共有类或接口

    3.2、导入import

    导入的是路径下的文件,不包含目录中文件下的的文件

    建议用url定义包名

    java pack.PackageDemo//需指定包

  • 相关阅读:
    java 读写word java 动态写入 模板文件
    Java代码获取NTP服务器时间
    Web环境使用相对路径发布Webservice
    eclipse 标记任务
    抽象工厂模式
    CentOS 7.0 使用yum 安装 Mariadb
    Centos 7 JDK 安装(默认之前没有安装过)
    深入浅出《设计模式》之外观模式(C++)
    深入浅出《设计模式》之工厂模式(C++)
    深入浅出《设计模式》之简单工厂模式(C++)
  • 原文地址:https://www.cnblogs.com/sunxlfree1206/p/4674197.html
Copyright © 2020-2023  润新知