一、多态

1. 概述

  • 理解:多态可以理解为事物存在的多种体(表)现形态。

    • 例如:

      • 动物中的猫和狗。
      • 猫这个对象对应的是猫类型,例如:猫 x = new 猫();
      • 同时猫也是动物中的一种,也可以把猫称为动物,例如:动物 y = new 猫();
      • 动物就是猫和狗这些具体事物中抽取出来的父类型,父类型的引用指向了子类对象。
  • 体现
    1. 父类的引用指向了子类的对象。
    2. 父类的引用也可以接收自己子类的对象。
      • 例如:Animal a = new Cat();

        • 父类型 a 的引用指向了子类的对象。
  • 前提
    1. 类与类之间必须有关系,要么是继承,要么是实现。
    2. 存在重写(覆盖),父类中有方法被子类重写(覆盖)。

2. 利与弊

  • 利:提高了程序的可扩展性和后期的可维护性。

  • 弊:只能使用父类中的引用去访问父类中的成员。

    • 使用了多态,父类型的引用在使用功能时,不能直接调用子类中特有的方法。

      • 例如:Animal a = new Cat();//多态的体现

        • 假设子类 Cat 中有抓老鼠的特有功能,父类型 a 就不能直接调用该功能,可以理解为 Cat 类型向上转型,提升了。
        • 父类的引用想要调用子类 Cat 中特有的方法,就要将父类的引用强制转换成子类的类型,向下转型。例如:Cat c = (Cat)a;
      • 注:
        • 如果父类可以创建对象的话,例如:Animal a = new Animal(); 就不能进行向下转型了,Cat c = (Cat)a; 这样编写代码在编译时会报错,不要出现将父类对象转换成子类类型。
        • 多态转换的是父类引用指向了自己子类的对象时,该引用可以被提升,也可以被强制转换,多态始终都是子类对象在做变化的。
  • 例如:

3. 特点

1. 成员变量

  • 无论编译还是运行时期,都参考左边(引用变量)所属的类。

    • 例如:多态中父类引用调用成员变量时,如果父类和子类有同名的成员变量,被调用的则是父类中的成员变量。

2. 非静态成员函数

  • 编译时期:参考引用型变量所属的类中是否有调用的方法,如果有,编译通过,如果没有,编译失败。

    • 例如:a.catchMouse();//编译报错,这种情况只能通过强制转换,向下转型后才可以使用子类中特有的功能。
  • 运行时期:参考对象所属的类中是否有调用的方法,如果父类中有一个非抽象方法,子类继承后将其重写(覆盖)了,多态运行时,父类的引用调用同名函数时,运行的是父类中的方法。
  • 总而言之:成员函数在多态调用时,编译看左边,运行看右边。

3. 静态成员函数

  • 无论编译还是运行时期,都参考左边,就是父类的引用在调用同名静态成员函数时,调用的是父类中的静态成员函数。

    • 原因:

      • 当类一被加载时,静态成员函数随类绑定在内存中,不需要创建对象,可以通过类名直接调用静态成员函数,并且父类中的静态成员函数一般是不被重写(覆盖)的。

      • 类在方法区中的分配:静态方法区和非静态方法区(关键字 super 和 this 在非静态方法区中)。

4. 应用

  1. 定义工具类,将共同行为封装在同一个类中。
  2. 对类型进行抽取(多态的产生)。
  3. 操作同一个父类型,对其中的子类型均可进行操作。
    • 例如:

二、内部类

1. 概述

  • 概述:将一个类定义在另一个类里面,定义在类里面的那个类称为内部类(内置类、嵌套类)。
  • 理解:当描述事物时,事物的内部还存在事物,事物内的事物使用内部类来描述,印务内部事物在使用外部事物的内容。
    • 例如:定义一个人的类,手、脚、心脏等等都属于人,这些又各自有自己的功能描述,这时候就可以在人这个描述类中,定义一些描述手、脚、心脏的类,也就是定义一些内部类。
  • 编译现象:编译 Java 文件时,如果类中有内部类,生成的 class 文件中会含有 Test$1.class 等等这样的文件,编译器会把内部类翻译为用 $(美元符号)分隔外部类名和内部类名的类文件,这是内部类的一种编译现象。

2. 访问规则

  1. 外部类要访问内部类,必须建立内部类的对象。
  2. 内部类可以直接访问外部类中的成员(包括私有成员)。
    • 原因:因为内部类中持有外部类的引用。
    • 格式:外部类名.this

3. 访问格式

  1. 内部类定义在外部类的成员位置,而且非私有时,可以在外部的其它类中直接建立内部类对象。

    • 格式:外部类名.内部类名 变量名 = 外部类对象.内部类对象;

      • 例如:Outer.Inner in = new Outer().new Inner();
    • 内部类定义在外部类的成员位置时,可以被成员修饰符所修饰。
      • 例如:

        • private:内部类在外部类中进行封装。
        • static:内部类有局部 statci 的特性,内部类被 static 修饰后,只能访问外部类中的 static 成员。
          • 外部的其它类访问 static 内部类中静态成员的格式:外部类名.内部类名.方法名();

            • 例如:Outer.Inner.function();
          • 外部的其它类访问 static 内部类中非静态成员的格式:new 外部类名.内部类名().方法名();
            • 例如:new Outer.Inner().function();
    • 注:
      1. 内部类中定义了静态成员时,该内部类必须是 static 的。
      2. 外部类中的静态方法访问内部类时,内部类也必须是 static 的。
      3. 实际开发中,内部类一般定义为 private,很少定义为 public 的。
  2. 内部类定义在局部位置
    1. 不可被成员修饰符所修饰,作用域限定在声明这个局部内部类的代码块中。

      • 例如:public、private、static 等修饰符。
    2. 可以直接访问外部类中的成员,还持有外部类的引用。
      • 注:内部类不可以访问所在局部中的非最终变量,只能访问被 final 修饰的局部变量。

      • 例如:

        • 分析:上述代码中的打印结果为 7、8,会改变,并没有因为被 final 所修饰就无法改变,原因是因为类调用方法结束后,被 final 修饰的变量已经从桟内存中消失,类再次调用方法时,已经是另一个变量了,所以可以重新传值。

4. 匿名内部类

  • 匿名内部类就是内部类的简写格式,匿名内部类其实就是一个匿名子类对象,可以理解为带内容的对象。

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

  • 定义匿名内部类的前提:

    • 匿名内部类必须是继承一个类或者实现接口。

      • 特殊情况:所有的类都有一个父类 Object,定义时也可用 Object。
  • 利与弊:

    • 利:简化书写。
    • 弊:
      1. 不能做强转的动作。
      2. 不能直接调用自己的特有方法。
      3. 如果继承的父类或接口中方法很多时,使用匿名内部类的可阅读性会非常差,调用也非常麻烦,因此匿名内部类中定义的方法一般不超过3个。
  • 例如:

三、异常

1. 概述

  • 异常是 Java 中的重要机制,使用面向对象的思想进行了封装,通常使用的是异常类。异常类中描述的就是程序中可能出现的错误或者问题。
  • 程序在运行时出现不正常的情况称为异常。
  • 由来:异常问题也是现实生活中一个具体的事物,可以通过 Java 中类的形式进行描述,并封装成对象,异常类就是 Java 对不正常的情况进行描述后的对象体现。
  • 程序中可能出现的错误或者问题:
    1. 用户输入错误导致的异常:非法参数、不按正常的使用程序等。
    2. 设备硬件等发生的错误的异常:硬盘损坏等。
    3. 物理限制的异常:存储空间不足、SDCard不存在等。
    4. 代码错误的异常:程序编写的方法不正确、返回错误的参数等。

2. 体系

异常问题的划分方式

  1. 严重的异常问题。

    • 严重的异常问题,Java 通过 Error 类进行描述,对于 Error 类一般不编写针对性的代码进行处理。
  2. 非严重的异常问题。
    • 非严重的异常问题,Java 通过 Exception 类进行描述,对于 Exception 类可以使用针对性的代码进行处理。

        注:无论是 Error 或 Exception 都具有一些共性内容,例如:不正常情况的相关信息、引发异常的原因等。

体系

  • Throwable

    • Error//出现重大异常问题。例如:运行的类不存在或者内存溢出等。
    • Exception//运行时出现的异常情况。
      • RuntimeException//特殊的异常类,Exception 的子类,抛出时不需要做声明。
  • 注:Error 和 Exception 的子类名称都是以父类名做为后缀。

特点

  1. 异常体系中所有类以及建立的对象都具备可抛性;
  2. 可以被 throw 和 throws 关键字所修饰操作;
  3. 只有异常体系才具备这个特点。

3. 分类

编译时异常

  • 异常在编译时,如果没有做任何处理(没有抛也没有 try),编译失败。
  • 异常被标识,代表可以被处理。

运行时异常

  • 编译时不需要处理,编译器不检查。
  • 异常发生时,Java 建议不处理,让程序停止。
  • 需要对代码进行修正。(例如:RuntimeException 以及 RuntimeException 的子类)

4. 处理

  • Java 中提供了特有的语句进行处理:

      try{
    需要检测的语句;
    }catch(异常类 变量){
    处理异常的语句(方式);
    }finally{
    一定要执行的语句;
    }
    • 这些特有语句的处理方式有三种结合情况:

        1.
      try{
      需要检测的语句;
      }catch(异常类 变量){
      处理异常的语句(方式);
      }
      2.
      try{
      需要检测的语句;
      }finally{
      一定要执行的语句;
      }
      3.
      try{
      需要检测的语句;
      }catch(异常类 变量){
      处理异常的语句(方式);
      }finally{
      一定要执行的语句;
      }
    • 注:

      1. finally 中定义的一般是关闭资源的代码,资源使用完后必须释放。
      2. 如果存在一些功能是必须执行的,可以使用 try{}finally{} 的方式,将必须执行的语句放在 finally 代码块中。
      3. finally 只有一种情况是不会执行的,在进入 finally 之前就先执行了 System.exit(0); 时,已经是退出了程序,finally 就不会执行的。
  • throw 和 throws 的用法:

    • throw 定义在函数内,用于抛出异常对象。
    • throws 定义在函数上,用于抛出异常类,可以抛出多个对象,使用 , 隔开即可。
      • 当函数的内容有 throw 抛出异常对象,但没 try 处理时,必须在函数上声明,否则会导致编译失败。
    • 注:RuntimeException 除外,函数内如果抛出的是 RuntimeException 异常,函数上不需要声明。
  • 抛出信息的处理:

    • 函数中出现了 throw 抛出异常对象时,要么是在函数内部进行 try 的处理,要么是在函数上声明,让函数的调用者去处理。

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

        getMessage();//获取异常信息,返回字符串
      toString();//获取异常类名和异常信息,返回字符串
      printStackTrace();//获取异常类名、异常信息以及异常在程序中出现的位置,返回值 void,JVM 默认的异常处理机制中,就是调用 PrintStackTrace() 方法来打印异常的堆栈跟踪信息
      printStackTrace(PrintStream s);//将异常内容保存在日志文件中

5. 自定义

  • 对于一些特有的问题,这些特有的问题没有被 Java 所描述封装为对象,对于这些特有的问题,可以按照 Java 的面向对象思想将问题进行自定义的异常封装,这就是自定义异常。

    • 自定义异常类继承 Exception 或 RuntimeException

      1. 让自定义异常类具备可抛性。
      2. 让自定义异常类具备操作异常的共性方法。
    • 如何自定义异常信息?
      • 自定义异常信息可以使用父类已定义好的功能,异常信息传递给父类的构造函数,由于父类中已经把异常信息的操作都完成了,子类只需在构造函数中,通过 super 语句将异常信息传递给父类,就可以通过 getMessage() 方法获取自定义的异常信息了。

      • 例如:

        • 说明:定义异常时,如果异常的发生,会导致无法继续进行运算,则让自定义异常类继承 RuntimeException。
      • 注意:自定义异常必须是自定义异常类有继承关系,一般继承 Exception。

        • 自定义异常类继承 Exception 的原因?

          • 异常体系的特点就是异常类和异常对象都具备可抛性,这个可抛性是 Throwable 体系中独有的特点,只有这个体系中的类和对象才可以被 throw 和 throws 所操作。

6. 好处与原则

好处

  1. 将问题进行封装。
  2. 将正常流程的代码和问题处理的代码分离,便于阅读。

原则

  1. 处理方式:try 或 throws。
  2. 调用到抛出异常的功能时,需要对所有抛出的异常进行处理,一个 try 可以对应多个 catch。
  3. 多个 catch 时,父类的 catch 需放到最后面,否则编译会报错,因为执行了父类的 catch 语句后,其余的 catch 语句将无法执行到。
  4. catch 中需要定义针对性的处理方式,一般不建议简单的定义 PrintStackTrace 输出语句,也不建议不做处理。
    1. 如果捕获的异常在本功能内处理不了的话,可继续在 catch 中抛出。

      • 例如:

    2. 如果捕获的异常在本功能内处理不了的话,但并不属于本功能出现的异常,可以将异常转换后再抛出。

    3. 如果捕获的异常在本功能内可以处理的话,但需要将异常产生后和本功能相关的问题提供出去给调用者,可以将异常转换后再抛出。

      • 例如:

7. 注意事项

  1. 异常问题在内部被解决就无需声明。
  2. catch 是用于处理异常,如果没有 catch,就代表异常问题没有被处理,该异常如果是检测时异常,就必须声明。
  3. 子父类重写(覆盖)时:
    1. 子类抛出的异常必须是父类异常的子类或者子集。
    2. 父类或接口没有异常抛出时,子类重写(覆盖)出现异常时,只能 try,不能抛。
      • 例如:

四、包(package)

1. 概述

  • Java 中将 package 称为包,相当于文件夹,包里面一般存放的是类文件。由于在编写程序时,难免存在类名相同的情况,为了便于对类进行分类管理,Java 便提供了包,以包的形式存放不同的类,在不同的包中可以有相同的类名,只需在调用时连同包名一起即可。

    • 包也是一种封装的形式。

2. 作用

  1. 为了避免多个类重名的情况,出现多个相同名字的类时,可通过包将其区分,避免冲突。
  2. 对类文件进行分类管理,可以将相关的类放在同个包中。
  3. 包的出现将 Java 的源文件和类文件分离。
  4. 给类提供了多层命名空间。
    • 例如:

      • a 包中的 Demo.class 文件,如果要创建 Demo 对象,在使用时需加上 a.
      • a.Demo demo = new a.Demo();

3. 规则

  1. 包必须写在程序的第一行,先有包,才知道类文件的存放位置。
  2. 类的全称:包.类名。
  3. 编译定义了包的程序文件时,在编译时需指定包的存放目录。
    • 例如:javac -d e:\Demo\mypack 类名.java

4. 包与包之间的访问

  1. 被访问的包里类的权限必须是 public。
  2. 访问其它包中的类时,需定义类的全称:包名.类名。
  3. 包如果不在当前路径的话,需使用 classpath 设置环境变量,为 JVM 指明路径。
  4. 类中的成员权限必须是 public 或 protected。
    • 类公有后,被访问的成员也要公有才能被访问。

    • protected 是为子类提供的一种权限。

    • 同个包中,protected 只做用为覆盖。

    • 不同包中的子类可以直接访问父类中被 protected 权限修饰符所修饰的成员。

    • 四种权限修饰符:

      • 注:由于被 public 所修饰的类名必须与 java 文件名相同,因此在一个 .java 文件中,不允许出现两个或以上的公有类或接口。

5. 导入(import)

  • 一个程序文件中只有一个 package,可以有多个 import,import 导入的是包中的类,不导入包中的包。
  • import 可以简化类名,在调用其它包中的类时,需要写类的全称,就是连同包名一起书写,当类存在多层包中时,使用 import 导入后,使用该类时,可以不加包名。
    • 例如:

      • a.b.c.pack.Demo
      • 导入的格式为 import a.b.c.pack.Demo;
      • 使用该类时,可直接写 Demo
  • 注意事项:
    1. 导入不同包中有想同类时,必须写类的全称以做区分,否则会报错。
    2. 定义包名不能重复,可以使用 url 来定义,url 是唯一的。
      • 例如:package com.java.Demo
    3. 导入包时,如果包中有很多类,可以使用通配符 * 代替包中所有的类,但不建议使用通配符 *,因为这样会将不需要使用的类一同导入,会占用内存空间,编写程序时,需要使用包里的哪些类就导入哪些类。

6. jar 包

  • 类越来越多时,可以使用包类封装。包越来越多时,可以将包进行压缩,Java 中通过 jar 工具对包进行压缩,压缩后的的后缀名为 jar。
  • jar.exe 工具的常用命令:
    • 创建 jar 包

      • jar -cvf mypack.jar mypack
    • 查看 jar 包
      • jar -tvf mypack.jar
    • 解压缩
      • jar -xvf mypack.jar
    • 自定义 jar 包的清单文件
      • jar -cvfm mypack.jar mypack.mf mypack
  • 好处:
    1. 数据库、驱动、SSH框架等都是以 jar 包体现的。
    2. 将多个包压缩为一个 jar 包文件,便于项目携带。
    3. 便于使用,只要在 classpath 设置 jar 包的路径,即可执行 jar 包中的 java 程序。

最新文章

  1. 使用Javascript中变量的setter属性
  2. oracle 创建database Link
  3. 【BZOJ 3282】Tree Link Cut Tree模板题
  4. Linux查看和改变网卡的一些信息
  5. 第一章 响应式设计之Media Quer
  6. shell脚本加密
  7. Java语言基本语法(一)————关键字&标识符(Java语言标识符命名规范&Java语言的包名、类名、接口名、变量名、函数名、常量名命名规则 )
  8. 在CentOS7上使用systemctl配置tomcat
  9. 2017 年的 人生 hard 模式终于结束了,2018年回归初心(二)
  10. 使用phpMyAdmin批量修改Mysql数据表前缀的方法
  11. (NO.00001)iOS游戏SpeedBoy Lite成形记(十一)
  12. VueJs(11)---vue-router(进阶2)
  13. IPC rtsp转发服务器搭建
  14. react build后直接从浏览器打开
  15. Luogu2336 SCOI2012 喵星球上的点名 SA、莫队
  16. 前端 HTML body标签相关内容 常用标签 表单标签 form
  17. 集合框架-Map集合
  18. css伪元素:before和:after用法详解
  19. K-th string
  20. 抽象语法符号ASN.1(Abstract Syntax Notation One)

热门文章

  1. 个人作业3——个人总结(Alpha阶段)
  2. 团队作业8----第二次项目冲刺(beta阶段)5.24
  3. 团队作业8----第二次项目冲刺(beta阶段)5.20
  4. 【Alpha】——Sixth Scrum Meeting
  5. 201521123097《Java程序设计》第六周学习总结
  6. 《Java程序设计》第5周学习总结
  7. 201521123122 《java程序设计》 第四周学习总结
  8. java程序设计-算术表达式的运算
  9. 解决python第三方插件下载慢的方法
  10. 翻译一篇关于jedis的文章