一、概念:
一个类的内部又完整的嵌套了另一个类结构。被嵌套的类称为内部类
类的五大成员【属性,方法,构造器,代码块,内部类】
内部类最大的特点就是可以直接访问外部类内的私有属性,并且可以体现类与类之间的包含关系
二、内部类分类
1、局部内部类(有类名)
定义在外部类的局部位置,比如方法中,有类名
/**
* 内部类学习
*/
public class InnerClass {
public static void main(String[] args) {
A a = new A();
a.method1();
}
}
class A { //外部类
private int n1 = 1;
public void method2() {}
public void method1() {
//1、局部内部类定义在外部类的局部位置,通常在方法内
//3、不能添加访问修饰符,但是可以用final修饰
//4、作用域:仅仅在定义它的方法或代码块中
final class Inner01 { //这就是局部内部类
//2、可以直接访问外部类的所有成员,包括私有
public void m1() {
System.out.println(n1);
method2();
}
}
//6、外部类在方法中,可以创建内部类对象,然后调用方法即可
Inner01 inner01 = new Inner01();
inner01.m1();
// class Inner02 extends Inner01{ //报错:无法继承
class Inner02 {}
}
//代码块局部内部类
{
class Inner03{}
}
}
注:
------外部类不能直接访问局部内部类;
------如果外部类和局部类的成员重名时,默认遵循就近原则访问,如果想访问外部类成员,可以使用(this.成员)去访问
2、匿名内部类(没有类名,划重点!!!!)
匿名内部类是定义在外部类的局部位置,比如方法中,并且没有类名
使用细节:等同于局部内部类
/**
* 内部类学习
*/
public class InnerClass {
public static void main(String[] args) {
B b = new B();
b.method01();
}
}
/**
* 匿名内部类
*/
class B{
private int n1 = 10;
public void method01(){
//基于接口的匿名内部类
//1、简化传统定义实现类的方式
//2、tiger的编译类型 IA,tiger的运行类型是 匿名内部类:外部类名 + $1
/*
等同于
class B$1 implements IA{
@Override
public void cry() {
System.out.println("老虎叫~~~~");
}
}
*/
//3、匿名内部类使用一次,就不能在使用了,tiger对象可以反复使用
IA tiger = new IA() {
@Override
public void cry() {
System.out.println("老虎叫~~~~");
}
};
System.out.println(tiger.getClass());//class day2.B$1
tiger.cry();
//基于类的匿名内部类
//father编译类型:Father ; 运行类型 : B$2
Father father = new Father("jack") {
public void test(){
System.out.println("匿名内部类重写test方法");
}
};
System.out.println(father.getClass());//class day2.B$2
}
}
interface IA{
public void cry();
}
class Father {
public Father(String name){}
public void test(){}
}
3、成员内部类(没有static修饰)
定义在外部类的成员位置,并且没有static修饰
/**
* 内部类学习
*/
public class InnerClass {
public static void main(String[] args) {
C c = new C();
/*
6、其他外部类,访问成员内部类
6-1、外部类对象.成员内部类对象.方法名 : c.new Innter01().say();
6-2、外部类中写一个方法,访问成员内部类: c.t1();
*/
}
}
/**
* 成员内部类
*/
class C{
private int n1 = 10;
public String name = "张三";
void method(){}
//成员内部类
//1、定义在成员外部
//2、可以添加任意访问修饰符(public,protected,默认,private)
//3、成员内部类访问外部类成员,可以直接访问
class Innter01{
public void say(){
//可以直接访问外部类所有成员,包含私有
System.out.println(n1+":"+name);
method();
}
}
//4、外部类访问成员内部类
public void t1(){
Innter01 innter01 = new Innter01();
innter01.say();
}
}
4、静态内部类(static修饰)
定义在外部类的成员位置,static修饰
/**
* 内部类学习
*/
public class InnerClass {
public static void main(String[] args) {
/*
6、其他外部类,访问静态内部类
6-1、new 外部类 . 静态内部类 new D.Inner01().say();
6-2、外类类中写一个方法,访问静态内部类: new D().method1();
*/
}
}
/**
* 静态内部类
*/
class D{
private int n1 = 10;
private static String name = "张三";
private static void cry(){}
/*
静态内部类
1、放在外部类的成员位置,static修饰
2、可以访问外部类的静态成员,不能访问普通成员
3、可以添加任意的访问修饰符(public,protected,默认,private)
4、静态内部类访问外部类成员 可以通过外部类名 + 属性名的方式
*/
static class Inner01{
String name = "李四";
public void say(){
System.out.println(D.name);
D.cry();
}
}
//5、外部类访问静态内部类,创建对象.静态内部类成员
public void method1(){
Inner01 inner01 = new Inner01();
inner01.say();
}
}