内部类(Inner Class),是 Java 中对 类 的一种定义方式,是 嵌套类 的一个分类,即非静态嵌套类(Non-Static Nested Class)。 内部类(非静态嵌套类)分为成员内部类、局部内部类和匿名内部类三种。
也可以简单分为两类
第一类:定义在外部类方法内位置上,分为局部内部类( 有类名)、匿名内部类(没有类名)。
第二类:定义在外部类的成员位置上,分为实例内部类(没有static修饰)、静态内部类(使用static修饰)。
在外部内的修饰限定符中,规定可以为 (public,default(包访问限定符)),且规定一个java文件中外部类中只能有一个public修饰的类且该类的类名必须要与该java文件名相同,而内部类呢,它实际上还是外部类的一个成员,它的级别与其他成员相同,允许与用修饰成员变量限定符修饰内部类。
注意事项:
1.定义在class 类名{}花括号外部的,即使是在一个文件里,都不能称为内部类
2.内部类和外部类共用同一个java源文件,但是经过编译之后,内部类会形成单独的字节码文件(一个类会生成一个对应的字节码文件)
概念:实例内部类是指没有用 static 修饰的内部类,有的地方也称为非静态内部类。
定义内部类对象:要知道内部类也是外部类的成员之一,所以如果要通过内部类实例化对象,前提必须是要有外部类对象的前提下
//new 构造方法
(方式1)外部类名.内部类名 内部类引用=外部类引用.new 内部类构造方法
(方式2)外部类名.内部类名 内部类引用=new 外部类构造方法.new 内部类构造方法
1.可以直接访问外部类的所有成员,包括私有的。外部类访问成员内部类访问方式:创建对象,再访问;
2.可以添加任意访问修饰符,因为它的地位就是一个外部类成员(包括public);
3.作用域和外部类的其他成员一样,为整个类体
4.如果外部类和内部类的成员重名时,内部类访问的话,遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问。
5.外部其他类访问成员内部类有三种方式:第一种实例化外部类,然后访问;第二种将内部类作为外部类的成员实例化然后访问;第三种在外部类里面编写一个方法,可以返回内部类对象。
6.实例内部类里面不能定义静态成员和方法
//定义外部类
class out{
public String name;
public int age;
out(){
System.out.println("这是外部类的无参构造函数");
}
public class inter{
public String sex;
//定义内部类
inter (){
System.out.println("这是内部类的无参构造函数");
}
}
}
public class javademo2 {
public static void main(String[] args) {
//先实例化外部类对象
out out1=new out();
//在外部类对象基础上,实例化内部类对象
out.inter inter1=out1.new inter();
}
}
例子2
package day2;
class Out1{
public int a1=1;
public static int a2=2;
public void fun1(){
Inter inter=new Inter();
inter.fun3();
}
public static void fun2(){
System.out.println();
}
public class Inter{
public int b1=3;
public final static int b2=4;
public void fun3(){
System.out.println(new Out().a1);
System.out.println(Out.a2);
System.out.println(b1);
System.out.println(b2);
}
//实例内部类中不能定义静态方法
// public static void fun4(){
//
// }
}
}
public class RealClass {
public static void main(String[] args) {
Out1 out1=new Out1();
//创建实例内部类对象
Out1.Inter inter=out1.new Inter();
//通过实例内部类访问外部类
inter.fun3();
out1.fun1();
}
}
1.定义实例内部类时,内部类中不能定义静态的成员变量(除非用final指定修饰)和方法。
2.外部类方法中不能直接访问内部类的成员变量和成员方法,如果要访问那就要在外部类中实例化内部类对象。
3.在内部类中同时包含了外部类的this和内部类的this,如果在内部类中有一个方法与外部类中的重名了,那调用时就会默认先调用内部类中的方法this.同名方法名
,如果要访问外部类中的重名方法,就要用外部类类名.this.同名方法名
。
//定义外部类
class out{
public String name;
public int age;
out(){
System.out.println("这是外部类的无参构造函数");
}
private void fun(){
System.out.println("外部类中的私有无参函数fun");
}
public static void fun1(){
System.out.println("外部类中的公有静态无参函数fun1");
}
public class inter{
public String sex;
//定义内部类
inter (){
System.out.println("这是内部类的无参构造函数");
}
public void fun1(){
System.out.println("内部类中的公有静态无参函数fun1");
}
public void test(){
//调用外部类中的fun方法
out.this.fun1();
//调用内部类中的fun方法
fun1();
}
}
}
public class javademo2 {
public static void main(String[] args) {
//先实例化外部类对象
out out1=new out();
//在外部类对象基础上,实例化内部类对象
out.inter inter1=out1.new inter();
//调用内部内中的test方法
inter1.test();
}
}
概念:静态内部类是指使用 static 修饰的内部类
值得注意的是,静态内部类对象的实例化不需要先实例化外部类对象(实例内部类相反)
//new 构造方法
(方式1)外部类名.内部类名 内部类引用=new 外部类名.内部类构造方法
(方式2)外部类名.内部类名 内部内引用=new 外部类构造方法.内部类构造方法
1.可以直接访问外部内的所有静态成员,包含私有的,但不能直接访问非静态的成员,如果非要访问那先要创建外部类对象
2.可以添加任意访问修饰符,因为它的地位就是一个成员;
3.作用域和外部类的其他成员一样,为整个类体
4.如果外部类和内部类的成员重名时,内部类访问的话,遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问。
class out{
public String name;
public int age;
public void fun(){
System.out.println("外部类中的fun方法");
}
static class inter{
public String sex;
public inter(){
System.out.println("静态内部类中的无参构造函数");
}
public void fun(){
System.out.println("静态类中的fun方法");
}
}
}
public class demo3 {
public static void main(String[] args) {
//实例化静态内部类对象
out.inter inter1=new out.inter();
}
}
1.定义静态内部类时,内部类中可以定义静态的成员变量和方法。
2. 在静态内部类方法中只能访问静态外部类成员,如果要访问外部类非静态成员则需要在静态内部类中实例化一个外部内对象
class out{
public String name;
public int age;
public void fun(){
System.out.println("外部类中的非静态fun方法");
}
public static void fun1(){
System.out.println("外部类中的静态方法fun1");
}
static class inter{
public String sex;
//静态内部类中定义静态成员变量
public static int a;
public inter(){
System.out.println("静态内部类中的无参构造函数");
}
public void fun(){
System.out.println("静态类中的fun方法");
}
//静态内部类中定义静态成员方法
public static void fun1(){
System.out.println("静态内部类中的静态成员方法fun1");
}
public void test(){
out.fun1();
//实例化外部类对象
out out1=new out();
out1.fun();
}
}
}
public class demo3 {
public static void main(String[] args) {
//实例化静态内部类对象
out.inter inter1=new out.inter();
//访问静态内部类的test方法
inter1.test();
}
}
概念:
概念:局部内部类是指在一个方法中定义的内部类,一般不会使用。
1.局部内部类与局部变量一样,类名前不能使用访问控制修饰符(public、private 和 protected)和 static 修饰符修饰,因为它的地位就是一个局部变量,局部变量是不能使用修饰符的。但是可以使用final修饰,因为局部变量也可以使用final。。
2.局部内部类只在当前方法中有效,也就是说作用域仅仅在定义它的方法或代码块中。
3.局部内部类中不能定义 static 成员。
4.局部内部类可以直接访问外部类的所有非静态成员和方法,包含私有的,访问方式——直接访问,如果访问外部内局类静态成员或方法,则先要在局部内部类中创建外部类对象进行访问。
5.外部类访问局部内部类,访问方式:创建对象,再访问(注意:必须在作用域内)
class out{
public String name;
public int age;
public out(){
System.out.println("外部类的无参构造函数");
}
//外部类的一个成员函数
public void fun(){
System.out.println("外部类的成员方法fun");
//外部类成员函数中定义的局部内部类
class inter{
private int A;
public int B;
protected int C;
public inter(){
System.out.println("局部内部类的无参构造函数");
}
public void fun(){
System.out.println("局部内部类的成员方法fun");
}
}
//在外部类的成员函数中实例化局部内部类对象
inter inter1=new inter();
inter1.fun();
}
}
public class demo4 {
public static void main(String[] args) {
//实例化外部内对象
out out1=new out();
//通过对象调用外部类fun方法
out1.fun();
}
}
例子2
package day2;
class Out{
public int a1=1;
public static int a2=2;
public void fun1(){
System.out.println("Out: 普通成员方法");
}
public static void fun2(){
System.out.println("Out: 静态成员方法");
}
//在外部类普通成员方法中使用【局部内部类】
public void test1(){
System.out.println("外部类普通成员方法:test1()");
class Inter1{
public int b1=3;
//局部内部类不能定义静态成员
//public static int b2=4;
//局部内部类普通成员方法
public void iFun1(){
System.out.println("普通成员方法:局部内部类可直接访问外部类成员(普通成员):"+a1);
fun1();
System.out.println("普通成员方法:局部内部类可直接访问外部类成员(静态成员):"+a2);
fun2();
}
//局部内部类同样也不能定义静态方法
// public static void iFun12(){
//
// }
}
Inter1 inter1=new Inter1();
inter1.iFun1();
}
//在外部类静态成员方法中使用【局部内部类】
public static void test2(){
System.out.println("外部类静态普通成员方法:test2()");
class Inter2{
public int b1=5;
//局部内部类不能定义静态成员
//public static int b2=6;
//局部内部类普通成员方法
public void iFun2(){
Out out=new Out();
System.out.println("局部内部类可直接访问外部类成员(普通成员):"+out.a1);
out.fun1();
System.out.println("局部内部类可直接访问外部类成员(静态成员):"+a2);
fun2();
}
}
Inter2 inter2=new Inter2();
inter2.iFun2();
}
}
public class PartClass {
public static void main(String[] args) {
Out out=new Out();
out.test1();
System.out.println("------------");
out.test2();
}
}