类是对一类事物的描述,是抽象的、概念上的定义

类是一组具有共同属性的对象。它是创建对象的模板。是一个逻辑实体。
Java中的类可以包含:

  1. 字段
  2. 方法
  3. 构造函数
  4. 嵌套类和接口

构造函数


为构造函数定义了两个规则。

  1. 构造函数名称必须与其类名相同
  2. 构造函数必须没有显式返回类型
  3. Java构造函数不能是抽象的,静态的,最终的和同步的

构造器的作用:

  1. 创建对象
  2. 初始化对象的信息

使用说明:

  1. 如果没显式的定义类的构造器的话,则系统默认提供一个空参的构造器
  2. 定义构造器的格式:权限修饰符 类名(形参列表){}
  3. 一个类中定义的多个构造器,彼此构成重载
  4. 一旦我们显式的定义了类的构造器之后,系统就不再提供默认的空参构造器
  5. 一个类中,至少会有一个构造器。
  6. 默认构造器的修饰符与所属类的修饰符一致
  7. 父类的构造器不可被子类继承

属性


属性分为:

  1. 实例变量
  2. 类变量 (静态变量)
  3. 局部变量

实例变量


  • 实例变量声明在一个类中,但在方法、构造方法和语句块之外;
  • 当一个对象被实例化之后,每个实例变量的值就跟着确定(有默认值 , 值和变量的类型有关);
  • 实例变量在对象创建的时候创建,在对象被销毁的时候销毁(实例变量时属于类的);
  • 实例变量可以声明在使用前或者使用后;
  • 实例变量具有默认值。数值型变量的默认值是0,布尔型变量的默认值是false,引用类型变量的默认值是null。变量的值可以在声明时指定,也可以在构造方法中指定;

类变量(静态变量)


  • 类变量也称为静态变量,在类中以 static 关键字声明,但必须在方法之外。
  • 无论一个类创建了多少个对象,静态变量只有一份。
  • 静态变量除了被声明为常量外很少使用。常量是指声明为public/private,final和static类型的变量。常量初始化后不可改变。
  • 静态变量储存在静态存储区。经常被声明为常量,很少单独使用static声明变量。
  • 静态变量在第一次被访问时创建,在程序结束时销毁。
  • 默认值和实例变量相似。数值型变量默认值是0,布尔型默认值是false,引用类型默认值是null。变量的值可以在声明的时候指定,也可以在构造方法中指定。此外,静态变量还可以在静态语句块中初始化。

局部变量


  • 局部变量声明在方法、构造方法或者语句块中;
  • 局部变量在方法、构造方法、或者语句块被执行的时候创建,当它们执行完成后,变量将会被销毁;
  • 访问修饰符不能用于局部变量;
  • 局部变量只在声明它的方法、构造方法或者语句块中可见;
  • 局部变量是在栈上分配的。
  • 局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用。

对象


对象是实际存在的该类事物的每个个体,因而也称为实例(instance)

具有状态和行为的实体被称为对象,例如 椅子,自行车,标记,笔,桌子,汽车等。它可以是物理的或逻辑的(有形的和无形的)。 无形对象的例子是银行系统。

一个对象有三个特征:

  1. 状态: 表示对象的数据(值)。
  2. 行为: 表示对象的行为(功能),例如存款,取款等。
  3. 身份: 对象身份通常通过唯一ID实现。 外部用户看不到ID的值。 但是,JVM在内部使用它来唯一地标识每个对象。

访问控制修饰符


Java中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。Java 支持 4 种不同的访问权限。

  1. default (即缺省,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
  2. private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
  3. public : 对所有类可见。使用对象:类、接口、变量、方法
  4. protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。 | 修饰符 | 类内部 | 同一个包 | b不同包的子类 | 同一个工程 | | —- | —- | —- | —- | —- | | private | yes | | | | | (缺省) | yes | yes | | | | protected | yes | yes | yes | | | public | yes | yes | yes | yes |

对于class的权限修饰只可以用public和default(缺省)。public 类可以在任意地方被访问。default 类只可以被同一个包内部的类访问。

封装


为什么需要封装?封装的作用和含义?

  1. 我们程序设计追求“高内聚,低耦合”。
    • 高内聚 :类的内部数据操作细节自己完成,不允许外部干涉;
    • 低耦合 :仅对外暴露少量的方法用于使用。
  2. 隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提高系统的可扩展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露的暴露出来。这就是封装性的设计思想。

可以通过将类的所有数据成员设为私有来创建Java中的完全封装类。现在我们可以使用setter和getter方法来设置和获取数据. 在Java Bean的类是完全封装的类的实例。

封装的优点 :

  1. 良好的封装能够减少耦合。
  2. 类内部的结构可以自由修改。
  3. 可以对成员变量进行更精确的控制。
  4. 隐藏信息,实现细节。

JavaBean


JavaBean是一种Java语言写成的可重用组件。
所谓javaBean,是指符合如下标准的Java类:

  1. 类是公共的
  2. 有一个无参的公共的构造器
  3. 有属性,且有对应的get、set方法

用户可以使用JavaBean将功能、处理、值、数据库访问和其他任何可以用Java代码创造的对象进行打包,并且其他的开发者可以通过内部的JSP页面、Servlet、其他JavaBean、applet程序或者应用来使用这些对象。用户可以认为JavaBean提供了一种随时随地的复制和粘贴的功能,而不用关心任何改变。

this 关键字


this表示当前对象

这里给出了java this个关键字的6个用法。

  1. this可以用来引用当前的类实例变量。
  2. this可以用来调用当前的类方法(隐式)
  3. this()可用于调用当前类构造函数。
  4. this可以作为方法调用中的参数传递。
  5. this可以在构造函数调用中作为参数传递。
  6. this可以用于从方法返回当前类实例。

注意:

  1. 可以在类的构造器中使用”this(形参列表)”的方式,调用本类中重载的其他的构造器!
  2. 明确:构造器中不能通过”this(形参列表)”的方式调用自身构造器
  3. 如果一个类中声明了n个构造器,则最多有 n - 1个构造器中使用了”this(形参列表)”
  4. “this(形参列表)”必须声明在类的构造器的首行!
  5. 在类的一个构造器中,最多只能声明一个”this(形参列表)”
  6. 使用this访问属性和方法时,如果在本类中未找到,会从父类中查找

继承


Java中继承背后的想法是,您可以创建基于现有类构建的新类。从现有类继承时,可以重用父类的方法和字段。此外,您还可以在当前类中添加新方法和字段。

作用:

  • 继承的出现减少了代码冗余,提高了代码的复用性。
  • 继承的出现,更有利于功能的扩展。
  • 继承的出现让类与类之间产生了关系,提供了多态的前提。

Java中继承性的说明:

  1. 子类继承了父类,就继承了父类的方法和属性。
  2. 在子类中,可以使用父类中定义的方法和属性,也可以创建新的数据和
    方法。
  3. 在Java 中,继承的关键字用的是extends,即子类不是父类的子集,
    而是对父类的“扩展”。

关于继承的规则:
子类不能直接访问父类中私有的(private)的成员变量和方法。

方法的重载


重载的概念:
在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。

重载的特点:
与返回值类型无关,只看参数列表,且参数列表必须不同。(参数个数或参数类型)。调用时,根据方法参数列表的不同来区别。

方法的重写


定义:
在子类中可以根据需要对从父类中继承来的方法进行改造,也称为方法的重置、覆盖。在程序执行时,子类的方法将覆盖父类的方法。

要求:

  1. 子类重写的方法必须和父类被重写的方法具有相同的方法名称、参数列表
  2. 子类重写的方法的返回值类型不能大于父类被重写的方法的返回值类型
  3. 子类重写的方法使用的访问权限不能小于父类被重写的方法的访问权限
  4. 子类不能重写父类中声明为private权限的方法
  5. 子类方法抛出的异常不能大于父类被重写方法的异常

注意:
子类与父类中同名同参数的方法必须同时声明为非static的(即为重写),或者同时声明为static的(不是重写)。因为static方法是属于类的,子类无法覆盖父类的方法。

super 关键字


在Java类中使用super来调用父类中的指定操作:

  1. super可用于访问父类中定义的属性
  2. super可用于调用父类中定义的成员方法
  3. super可用于在子类构造器中调用父类的构造器

注意:

  1. 尤其当子父类出现同名成员时,可以用super表明调用的是父类中的成员
  2. super的追溯不仅限于直接父类
  3. super和this的用法相像,this代表本类对象的引用,super代表父类的内存空间的标识

调用父类的构造器:

  1. 子类中所有的构造器默认都会访问父类中空参数的构造器
  2. 当父类中没有空参数的构造器时,子类的构造器必须通过this(参数列表)或者super(参数列表)语句指定调用本类或者父类中相应的构造器。同时,只能”二选一”,且必须放在构造器的首行
  3. 如果子类构造器中既未显式调用父类或本类的构造器,且父类中又没有无参的构造器,则编译出错

thissuper 的区别

NO. 区别点 this super
1 访问属性 访问本类中的属性,如果本类没
有此属性则从父类中继续查找
直接访问父类中的属性
2 调用方法 访问本类中的方法,如果本类没
有此方法则从父类中继续查找
直接访问父类中的方法
3 调用构造器 调用本类构造器,必须放在构造
器的首行
调用父类构造器,必须
放在子类构造器的首行

多态性


多态性,是面向对象中最重要的概念,在Java中的体现:

  • 对象的多态性:父类的引用指向子类的对象
  • 可以直接应用在抽象类和接口上

Java引用变量有两个类型:编译时类型运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。简称:编译时,看左边;运行时,看右边。

  1. 若编译时类型和运行时类型不一致,就出现了对象的多态性(Polymorphism)
  2. 多态情况下,“看左边”:看的是父类的引用(父类中不具备子类特有的方法)
    “看右边”:看的是子类的对象(实际运行的是子类重写父类的方法)

一个引用类型变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法

虚拟方法调用(多态情况下)

  • 子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法,父类根据赋给它的不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法确定的。

从编译和运行的角度看:

  • 重载,是指允许存在多个同名方法,而这些方法的参数不同。编译器根据方法不同的参数表,对同名方法的名称做修饰。对于编译器而言,这些同名方法就成了不同的方法。它们的调用地址在编译期就绑定了。Java的重载是可以包括父类和子类的,即子类可以重载父类的同名不同参数的方法。所以:对于重载而言,在方法调用之前,编译器就已经确定了所要调用的方法,这称为“早绑定”或“静态绑定”;而对于多态,只有等到方法调用的那一刻,解释运行器才会确定所要调用的具体方法,这称为“晚绑定”或“动态绑定”。

多态作用:

  • 提高了代码的通用性,常称作接口重用

前提:

  • 需要存在继承或者实现关系
  • 有方法的重写

成员方法:

  • 编译时:要查看引用变量所声明的类中是否有所调用的方法。
  • 运行时:调用实际new的对象所属的类中的重写方法。

成员变量:

  • 不具备多态性,只看引用变量所声明的类。

子类继承父类

  • 若子类重写了父类方法,就意味着子类里定义的方法彻底覆盖了父类里的
    同名方法,系统将不可能把父类里的方法转移到子类中。
  • 对于实例变量则不存在这样的现象,即使子类里定义了与父类完全相同的
    实例变量,这个实例变量依然不可能覆盖父类中定义的实例变量

    instanceof 操作符


x instanceof A:检验x是否为类A的对象,返回值为boolean型。

  • 要求x所属的类与类A必须是子类和父类的关系,否则编译错误。
  • 如果x属于类A的子类B,x instanceof A值也为true。

对象类型转换 (Casting )


基本数据类型的Casting:
自动类型转换:小的数据类型可以自动转换成大的数据类型

  1. int a=10;
  2. float b=a;

强制类型转换:可以把大的数据类型强制转换(casting)成小的数据类型

  1. float a = 10.9f;
  2. int b=(int)a;

对Java对象的强制类型转换称为造型

  1. 从子类到父类的类型转换可以自动进行
  2. 从父类到子类的类型转换必须通过造型(强制类型转换)实现
  3. 无继承关系的引用类型间的转换是非法的
  4. 在造型前可以使用instanceof操作符测试一个对象的类型

字符串转换成基本数据类型

  • 通过包装类的构造器实现:int i = new Integer(“12”);
  • 通过包装类的parseXxx(String s)静态方法:Float f = Float.parseFloat(“12.1”);

基本数据类型转换成字符串
调用字符串重载的valueOf()方法:String fstr = String.valueOf(2.34f);

Object 类的使用


Object类是所有Java类的根父类 , 如果在类的声明中未使用extends关键字指明其父类,则默认父类
java.lang.Object

Object类中的主要结构:

  1. public Object() 构造器
  2. public boolean equals(Object obj) 对象比较
  3. public int hashCode() 取得Hash码
  4. public String toString() 对象打印时调用

==和equals的区别


  1. == 既可以比较基本类型也可以比较引用类型。对于基本类型就是比较值,对于引用类型就是比较内存地址
  2. equals的话,它是属于java.lang.Object类里面的方法,如果该方法没有被重写过默认也是==;我们可以看到String等类的equals方法是被重写过的,而且String类在日常开发中用的比较多,久而久之,形成了equals是比较值的错误观点。
  3. 具体要看自定义类里有没有重写Object的equals方法来判断。
  4. 通常情况下,重写equals方法,会比较类中的相应属性是否都相等。

包装类的使用


针对八种基本数据类型定义相应的引用类型—包装类(封装类)
有了类的特点,就可以调用类中的方法,Java才是真正的面向对象

基本数据类型 包装类型
byte Byte
short Short
int Integer
long Long
float Float
double Double
boolean Boolean
char Character

装箱

基本数据类型转换为对象类型

  • 通过包装类的构造器实现:int i = 500; Integer t = new Integer(i);
  • 还可以通过字符串参数构造包装类对象:
    Float f = new Float(“4.56”);
    Long l = new Long(“asdf”); //NumberFormatException

拆箱

对象类型类型转换为基本数据

  • 调用包装类的.xxxValue()方法:boolean b = bObj.booleanValue();

    static 关键字


当我们编写一个类时,其实就是在描述其对象的属性和行为,而并没有产生实质上的对象,只有通过new关键字才会产生出对象,这时系统才会分配内存空间给对象,其方法才可以供外部调用。我们有时候希望无论是否产生了对象或无论产生了多少对象的情况下,某些特定的数据在内存空间里只有一份,例如所有的中国人都有个国家名称,每一个中国人都共享这个国家名称,不必在每一个中国人的实例对象中都单独分配一个用于代表国家名称的变量。

类属性、类方法的设计思想

  • 类属性作为该类各个对象之间共享的变量。在设计类时,分析哪些属性不因对象的不同而改变,将这些属性设置为类属性。相应的方法设置为类方法。
  • 如果方法与调用者无关,则这样的方法通常被声明为类方法,由于不需要创建对象就可以调用类方法,从而简化了方法的调用。

使用范围:

  • 在Java类中,可用static修饰属性、方法、代码块、内部类

被修饰后的成员具备以下特点:

  • 随着类的加载而加载
  • 优先于对象存在
  • 修饰的成员,被所有对象所共享
  • 访问权限允许时,可不创建对象,直接被类调用

注意:

  • 在static方法内部只能访问类的static修饰的属性或方法,不能访问类的非static的结构。
  • 因为不需要实例就可以访问static方法,因此static方法内部不能有thissuper
  • static修饰的方法不能被重写

单例设计模式


所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。如果我们要让类在一个虚拟机中只能产生一个对象,我们首先必须将类的构造器的访问权限设置为private,这样,就不能用new操作符在类的外部产生类的对象了,但在类内部仍可以产生该类的对象。因为在类的外部开始还无法得到类的对象,只能调用该类的某个静态方法以返回类内部创建的对象,静态方法只能访问类中的静态成员变量,所以,指向类内部产生的该类对象的变量也必须定义成静态的。

单例设计模式-饿汉式

饿汉式是线程安全的

  1. class Singleton {
  2. // 4.此实例也必须静态化
  3. private static Singleton single = new Singleton();
  4. // 1.私有化构造器
  5. private Singleton() {
  6. }
  7. // 3.提供公共的静态的方法,返回当前类的对象
  8. public static Singleton getInstance() {
  9. return single;
  10. }
  11. }

单例设计模式-懒汉式

懒汉式是线程不安全的

  1. class Singleton {
  2. // 1.私有化构造器
  3. private Singleton() {
  4. }
  5. // 2.内部提供一个当前类的实例
  6. // 4.此实例也必须静态化
  7. private static Singleton single;
  8. // 3.提供公共的静态的方法,返回当前类的对象
  9. public static Singleton getInstance() {
  10. if (single == null) {
  11. synchronized (Singleton.class) {
  12. single = new Singleton();
  13. }
  14. }
  15. return single;
  16. }
  17. }

单例模式的优点:

由于单例模式只生成一个实例,减少了系统性能开销,当一个对象的产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方式来解决。

单例设计模式-应用场景

  1. 网站的计数器,一般也是单例模式实现,否则难以同步。
  2. 应用程序的日志应用,一般都使用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。
  3. 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。
  4. 项目中,读取配置文件的类,一般也只有一个对象。没有必要每次使用配置文件数据,都生成一个对象去读取。
  5. Application 也是单例的典型应用
  6. Windows的Task Manager (任务管理器)就是很典型的单例模式
  7. Windows的Recycle Bin (回收站)也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例。

理解main方法的语法


  • 由于Java虚拟机需要调用类的main()方法,所以该方法的访问权限必须是public,又因为Java虚拟机在执行main()方法时不必创建对象,所以该方法必须是static的,该方法接收一个String类型的数组参数,该数组中保存执行Java命令时传递给所运行的类的参数。
  • 又因为main() 方法是静态的,我们不能直接访问该类中的非静态成员,必须创建该类的一个实例对象后,才能通过这个对象去访问类中的非静态成员.

代码块


代码块(或初始化块)的作用:

  • 对Java类或对象进行初始化
  • 代码块(或初始化块)的分类:
    • 一个类中代码块若有修饰符,则只能被static修饰,称为静态代码块(static block),没有使用static修饰的,为非静态代码块。
    • static代码块通常用于初始化static的属性

非静态代码块:没有static修饰的代码块

  1. 可以有输出语句。
  2. 可以对类的属性、类的声明进行初始化操作。
  3. 除了调用非静态的结构外,还可以调用静态的变量或方法。
  4. 若有多个非静态的代码块,那么按照从上到下的顺序依次执行。
  5. 每次创建对象的时候,都会执行一次。且先于构造器执行。

静态代码块:用static 修饰的代码块

  1. 可以有输出语句。
  2. 可以对类的属性、类的声明进行初始化操作。
  3. 不可以对非静态的属性初始化。即:不可以调用非静态的属性和方法。
  4. 若有多个静态的代码块,那么按照从上到下的顺序依次执行。
  5. 静态代码块的执行要先于非静态代码块。
  6. 静态代码块随着类的加载而加载,且只执行一次。

final 关键字


在Java中声明类、变量和方法时,可使用关键字final来修饰,表示“最终的”。

  1. final标记的类不能被继承。提高安全性,提高程序的可读性。
    • String类、System类、StringBuffer类
  2. final标记的方法不能被子类重写。
    • 比如:Object类中的getClass()。
  3. final标记的变量(成员变量或局部变量)即称为常量。名称大写,且只能被赋值一次。
  4. final标记的成员变量必须在声明时或在每个构造器中或代码块中显式赋值,然后才能使用。
    • final double MY_PI = 3.14;

抽象类


随着继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一般,更通用。类的设计应该保证父类和子类能够共享特征。有时将一个父类设计得非常抽象,以至于它没有具体的实例,这样的类叫做抽象类。

  1. 用abstract关键字来修饰一个类,这个类叫做抽象类。
  2. 用abstract来修饰一个方法,该方法叫做抽象方法。
  3. 抽象方法:只有方法的声明,没有方法的实现。以分号结束:
    1. 比如:public abstract void talk();
  4. 含有抽象方法的类必须被声明为抽象类。
  5. 抽象类不能被实例化。抽象类是用来被继承的,抽象类的子类必须重写父类的抽象方法,并提供方法体。若没有重写全部的抽象方法,仍为抽象类。
  6. 不能用abstract修饰变量、代码块、构造器;
  7. 不能用abstract修饰私有方法、静态方法、final的方法、final的类。

抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。

接口的特点:


  1. 用interface来定义。
  2. 接口中的所有成员变量都默认是由public static final修饰的。
  3. 接口中的所有抽象方法都默认是由public abstract修饰的。
  4. 接口中没有构造器。
  5. 接口采用多继承机制。

接口中的默认方法

  1. 若一个接口中定义了一个默认方法,而另外一个接口中也定义了一个同名同参数的方法(不管此方法是否是默认方法),在实现类同时实现了这两个接口时,会出现:接口冲突。
    • 解决办法:实现类必须覆盖接口中同名同参数的方法,来解决冲突。
  2. 若一个接口中定义了一个默认方法,而父类中也定义了一个同名同参数的非抽象方法,则不会出现冲突问题。因为此时遵守:类优先原则。接口中具有相同名称和参数的默认方法会被忽略。

内部类


  • 当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构最好使用内部类。
  • 在Java中,允许一个类的定义位于另一个类的内部,前者称为内部类,后者称为外部类。
  • Inner class一般用在定义它的类或语句块之内,在外部引用它时必须给出完整的名称。
  • Inner class的名字不能与包含它的外部类类名相同;
  • 分类:
    1. 成员内部类(static成员内部类和非static成员内部类)
    2. 局部内部类(不谈修饰符)、匿名内部类

成员内部类作为类的成员的角色:

  1. 和外部类不同,Inner class还可以声明为private或protected;
  2. 可以调用外部类的结构
  3. Inner class 可以声明为static的,但此时就不能再使用外层类的非static的成员变量;

成员内部类作为类的角色:

  1. 可以在内部定义属性、方法、构造器等结构
  2. 可以声明为abstract类 ,因此可以被其它的内部类继承
  3. 可以声明为final的
  4. 编译以后生成OuterClass$InnerClass.class字节码文件(也适用于局部内部类)

【注意】

  1. 非static的成员内部类中的成员不能声明为static的,只有在外部类或static的成员内部类中才可声明static成员。
  2. 外部类访问成员内部类的成员,需要“内部类.成员”或“内部类对象.成员”的方式
  3. 成员内部类可以直接使用外部类的所有成员,包括私有的数据
  4. 当想要在外部类的静态成员部分使用内部类时,可以考虑内部类声明为静态的

如何创建成员内部类的对象?(静态的,非静态的)

  1. //创建静态的Dog内部类的实例(静态的成员内部类):
  2. Person.Dog dog = new Person.Dog();
  3. //创建非静态的Bird内部类的实例(非静态的成员内部类):
  4. //Person.Bird bird = new Person.Bird();//错误的
  5. Person p = new Person();
  6. Person.Bird bird = p.new Bird();

局部内部类


  1. 内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号,以及数字编号。
  2. 只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方都不能使用该类。
  3. 局部内部类可以使用外部类的成员,包括私有的。
  4. 局部内部类可以使用外部方法的局部变量,但是必须是final的。由局部内部类和局部变量的声明周期不同所致。
  5. 局部内部类和局部变量地位类似,不能使用public,protected,缺省,private
  6. 局部内部类不能使用static修饰,因此也不能包含静态成员

如何使用局部内部类

  1. 只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方都不能使用该类
  2. 但是它的对象可以通过外部方法的返回值返回使用,返回值类型只能是局部内部类的父类或父接口类型
  1. // 方式一 : 返回一个实现了Comparable接口的类的对象
  2. public Comparable getComparable(){
  3. //创建一个实现了Comparable接口的类:局部内部类
  4. class MyComparable implements Comparable{
  5. @Override
  6. public int compareTo(Object o) {
  7. return 0;
  8. }
  9. }
  10. return new MyComparable();
  11. }
  12. // 方式二
  13. public Comparable getComparable(){
  14. return new Comparable(){
  15. @Override
  16. public int compareTo(Object o) {
  17. return 0;
  18. }
  19. };
  20. }

匿名内部类


匿名内部类不能定义任何静态成员、方法和类,只能创建匿名内部类的一个实例。一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。**

  1. 匿名内部类必须继承父类或实现接口
  2. 匿名内部类只能有一个对象
  3. 匿名内部类对象只能使用多态形式引用