- 介绍
- 定义
- 成员内部类
- 语法格式
- 使用说明
- 代码示例
- 局部内部类
- 语法格式
- 使用说明
- 代码示例
- 匿名内部类
- 语法格式
- 使用说明
- 代码示例
- 静态内部类
- 语法格式
- 使用说明
- 代码示例
Java中已经有了类,为什么还要有内部类呢?
这是因为当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,不在其他地方单独使用,那么整个内部的完整结构最好使用内部类。就相当于把人可以定义为一个类,但是人的身体内的某些器官也是需要一个完整的结构来描述,其可以为外部事物提供服务,则它就可以定义为内部类。
定义将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,外面的类B则称为外部类。
内部类一般来说包括四种:
- 成员内部类
- 局部内部类
- 匿名内部类
- 静态内部类
对于内部类的相关使用,根据实际需要,一般可以分为三种情况:
- 外部类使用内部类
- 内部类使用外部类
- 其他类使用内部类
下面将对这四种内部类及其三种使用情况进行详细解释说明
成员内部类 语法格式类体中(和其他成员在同级别的位置)
【修饰符】 class 外部类名{
【修饰符】 class 内部类名{
}
}
使用说明成员:五大成员都可以存在!但是不能有静态资源
修饰符:四个访问修饰符都可以修饰,abstract final都可以单独使用
内部类使用外部类
内部类使用成员外部类的资源时,直接访问就可以
外部类使用内部类
不能直接访问,需要实例化对象,然后使用对象调用
其他类使用内部类方法
不能直接使用,必须实例化对象使用,实例化方法和正常类的实例化有些不一样。方法如下:
先创建外部类对象:外部类 名称1 = new 外部类(); 再创建内部类对象:外部类.内部类 名称2 = 名称1.new 内部类(); 或者: 直接创建:外部类.内部类 名称 = new 外部类().new 内部类();
注意:
外部类和内部类属性或者方法重名会发生冲突,需要通过下面的方法进行区分
this.内容 //this是当前对象 外部类.this.内容 //外部类的对象代码示例
public class Outer {
private int id = 10;
private int age;
private String name;
private static String test;
//构造器
public Outer() {
}
{
//代码块
}
Inner inner = new Inner();
//外部方法
public void mathod1(){
System.out.println("Outer的方法");
System.out.println(inner.sex); //不能直接调用内部类的属性,需要创建对象
inner.method2();//不能直接调用内部类的属性,需要创建对象
}
//成员内部类
public class Inner{
private int id = 20;
private String name;
// private static String test; 不能有静态资源
public Inner() {
}
{
//代码块
}
public void method2(){
System.out.println("Inner的方法");
System.out.println(age); //可以调到Outer的属性
// mathod1();//可以调到Outer的属性
//内部类和外部类重名
System.out.println(this.id); //使用的是内部类的属性
System.out.println(Outer.this.id);//使用的是外部类的属性
}
}
}
public class Demo5 {
public static void main(String[] args) {
//其他类使用成员内部类的方法
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
//或者用下面方法
Outer.Inner inner1 = new Outer().new Inner();
}
局部内部类
局部内部类又称为方法内部类,在某个局部(方法内)
语法格式【修饰符】 class 外部类{
【修饰符】 返回值类型 方法名(【形参列表】){
【final/abstract】 class 内部类{
}
}
}
使用说明成员:五大成员都可以存在,但是不包括静态资源
修饰符:abstract final可以单独修饰,不可以使用访问修饰符
内部类使用外部类
内部类使用成员外部类的资源时,直接访问就可以
外部类使用内部类
局部内部类只能在当前局部(方法)使用,其他地方无法使用,使用的时候通过实例化对象的形式方法。
其他类使用内部类方法
访问不到
注意:
外部类和内部类属性或者方法重名会发生冲突,需要通过下面的方法进行区分(默认就近原则)
this //当前对象 uther.this //外部类对象
如果当前局部存在局部变量,当在内部类使用该变量时,这个变量必须为常量。否则编译不通过
代码示例public class Outer {
private int id = 10;
private int age;
private String name;
private static String test;
public Outer() {
}
{
//代码块
}
public void mathod1(){
System.out.println("Outer的方法");
}
public void function(){
//方法(局部内部类)内部类
class Inner3{
private String email;
Inner3(){
}
{
//方法块
}
public void inner3Method(){
System.out.println(id); //直接使用外部资源
mathod1();
}
}
Inner3 inner3 = new Inner3();
System.out.println(inner3.email); //当前方法(局部)可以通过实例化对象使用,其他地方无法使用
}
}
匿名内部类
有时需要用到一个抽象类的子类的对象或一个接口的实现类的对象,而且只需要创建一个对象(只使用一次),这时候可以使用匿名内部类,避免费时费力给类命名的问题。(但也会有复用性差的缺点)
语法格式因为匿名内部类必须是抽象类的子类或者接口的实现类,所以其可以按照下面的步骤实现:
- 1.编写类,继承这个父类或实现这个接口
- 2.重写父类或父接口的方法
- 3.创建这个子类或实现类的对象
new 父类(【实参列表】){
重写方法...
}
//或者
new 父接口(){
重写方法...
}
使用说明匿名内部类是一种特色的局部内部类,只不过没有名称而已。
匿名内部类为局部内部类,所以,局部内部类的所有限制都对其有效
内部类使用外部类
内部类使用成员外部类的资源时,直接访问就可以
外部类使用内部类
局部内部类只能在当前局部(方法)使用,其他地方无法使用,使用的时候通过实例化对象的形式方法。
其他类使用内部类方法
访问不到
注意:
- 1.匿名内部类不能有构造方法。
- 2.匿名内部类不能定义任何静态成员,方法和类。
- 3.匿名内部类不能使用public,protected,private,static。
package com.atguigu.demo;
import com.atguigu.bean.Employee;
import java.util.Arrays;
import java.util.Comparator;
public class Demo4 {
public static void main(String[] args) {
int id = 0;
Employee[] employees = new Employee[5];
employees[0] = new Employee(1,"jack1",2001);
employees[1] = new Employee(2,"jack2",1001);
employees[2] = new Employee(3,"jack3",5000);
employees[3] = new Employee(4,"jack4",2002);
employees[4] = new Employee(5,"jack5",3000);
Comparator comparator = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 == o2)
return 1;
if (o1 instanceof Employee && o2 instanceof Employee){
Employee employee1 = (Employee) o1;
Employee employee2 = (Employee) o2;
return (int) (employee1.getSalary() - employee2.getSalary());
}
return -1;
}
public int age;
// public static int age;
public void method(){
System.out.println("内明内部类");
System.out.println(id); //直接访问外部资源
}
};
Arrays.sort(employees,comparator);
for (int i = 0; i < employees.length; i++) {
System.out.println(employees[i]);
}
}
}
静态内部类
静态内部类在类体中(和其他成员在同级别的位置)
语法格式【修饰符】 class 外部类{
【其他修饰符】 static class 内部类{
}
}
使用说明五大成员都可以存在!但是不能有静态资源
四个访问修饰符都可以修饰,abstract final都可以单独使用
内部类使用外部类
静态资源可以直接使用;非静态资源需要实例化对象使用
外部类使用内部类
静态资源直接使用类名调用;非静态资源实例化对象调用
其他类使用内部类方法
不在依赖于外部嘞的对象, 直接实例化对象即可
注意:
外部类的静态资源和内部类的普通资源如果同名,需要通过静态资源通过类名调用进行区分。
public class Outer {
private int id = 10;
private int age;
private String name;
private static String test;
public Outer() {
}
{
//代码块
}
Inner inner = new Inner();
public void mathod1(){
Inner2 inner2 = new Inner2();
System.out.println("Outer的方法");
System.out.println(Inner2.address);
System.out.println(inner2.age);
}
//静态内部类
public static class Inner2{
private int age;
private static String name;
private static String address;
public Inner2() {
}
static {
//代码块
}
public static void inner2Method(){
Outer outer = new Outer();
System.out.println("静态内部类的方法");
System.out.println(outer.id); //不能直接使用外部类的非静态属性,需要通过对象调用
outer.mathod1();//不能直接使用外部类的非静态方法,需要通过对象调用
System.out.println(test);//静态资源可以直接调用
}
}
}
本文的其他类是用的挎包的测试类进行举例



