10.java内部类

本文详细介绍了Java中的四种内部类:成员内部类、方法内部类、静态嵌套类和匿名内部类。成员内部类可以拥有实例变量和方法,不能有静态元素,并且可以访问外部类的所有成员。方法内部类相当于局部变量,不能有访问修饰符,可以访问本方法和外部类的成员。静态嵌套类类似于静态变量,可以有静态和实例成员,但不能有this。匿名内部类用于快速创建子类实例,常用于接口实现。
摘要由CSDN通过智能技术生成

10.java内部类

       包含在类中的内就是内部类,包含内部类的类是外部类。

      内部类有四种:成员内部类,方法内部类,静态嵌套类,匿名内部类

1.成员内部类

       相当于java类中的成员变量基本结构:

public class TestClass{

                       public class InnerClass {

}

}

内部类编译后会形成一个新的字节码文件【外部类类名$内部类类型.class】

1.1成员内部类用法

      (1)成员内部类可以使用任意的访问限制修饰符

public class TestClass {

      //成员内部类可以使用任意的访问限制修饰符

      public class InnerClass{ }

      protected class InnerClass1{ }

      class InnerClass2{ }

      private class InnerClass3{ }

}

      (2)成员内部类可以有实例变量、实例方法、构造方法,不能有静态元素

代码测试:

public class TestClass {

      //成员内部类

      public  class InnerClass{

            //成员内部类可以有实例变量、实例方法、构造方法,不能有静态元素

            int id=10;//成员内部类实例变量

            //static String name="zhangsan";//报错,成员内部类不能有静态变量

            public void Innermethod(){

                  System.out.println("成员内部类的实例方法");

            }

            public InnerClass(){

                  System.out.println("成员内部类的构造方法");

            }

            //public static void staticInnermethod(){}//报错,成员内部类不能有静态方法

      }

}

      (3)成员内部类中的构造方法可以访问其他的构造方法【new】,可以访问实例变量/方法【对象.实例变量/方法,this.实例变量/方法,可以省略对象/this】

       (4)成员内部类中的实例方法可以访问构造方法【new】,可以访问实例变量/方法【对象.实例变量/方法,this.实例变量/方法,可以省略对象/this】。

       (5)成员内部类中的构造方法可以访问外内部类的构造方法,实例方法/变量,类方法/变量。

       (6)成员内部类中的实例方法可以访问外部类的构造方法,实例方法/变量,类方法/变量。

       (7)外内部类中的构造方法/实例法可以访问成员内部类的构造方法,实例方法/变量,外内部类中的类方法不能访问成员内部类。

                 外部类访问内部内时,用.this和省略都会错,只能对象访问。

                 外内部类中的类方法,new内部类对象报错

       (8)其他类中是可以访问成员内部类的,需要依赖外部类对象【new外部类类名().new 静态嵌套类名()】,注意访问限制修饰符。

               也是不能用this.和省略

public class TestClass {

      public String name="wuwei";//外部类实例变量

      public static String lsp="sss";//外部类静态成员变量

      public void outMethod(){

            System.out.println("外部类的实例方法");

            new InnerClass();

            new InnerClass().id=1001;

            new InnerClass().Innermethod1();

            //InnerClass.this.id=1000;报错

            //id=1000;报错

      }

      public static void staticOutMethod(){

            System.out.println("外部类的静态方法");

            //new InnerClass();报错

      }

      public TestClass(){

            System.out.println("外部类的构造方法");

            new InnerClass();

            new InnerClass().id=1001;

            new InnerClass().Innermethod1();

            //InnerClass.this.id=1000;报错

            //id=1000;报错

      }

      //成员内部类

      public  class InnerClass{

            //成员内部类可以有实例变量、实例方法、构造方法,不能有静态元素

            int id=10;//成员内部类实例变量

            //static String name="zhangsan";//报错,成员内部类不能有静态变量

            public void Innermethod1(){

                  System.out.println("成员内部类的实例方法1");

                  new TestClass();//访问外部类

                  new TestClass().name="zj";//访问外部类实例变量方法1

                  TestClass.this.name="zj";//访问外部类实例变量方法2

                  new TestClass().lsp="sss";//访问外部类静态变量

                  TestClass.this.staticOutMethod();

                  TestClass.this.lsp="sss";

                  new TestClass().staticOutMethod();//访问外部类静态方法

                  //TestClass.this表示外部类这个当前类

                  new TestClass().outMethod();//访问外部类实例方法,方法1

                  TestClass.this.outMethod();//访问外部类实例方法,方法2

                  //还可以省略

                  outMethod();

                  name="zj";



            }

            public void Innermethod2(){

                  System.out.println("成员内部类的实例方法2");

                  InnerClass ic=new InnerClass("lisi");//访问其他构造方法,内部类的对象

                  ic.id=11;//访问实例变量方式1

                  this.id=12;//访问实例变量方式2

                  id=13;//访问实例变量方式3,this和对象可以省略,

                  ic.Innermethod1();//访问实例方法1

                  this.Innermethod1();//访问实例方法2

                  Innermethod1();//访问实例方法3

            }

            public InnerClass(){

                  System.out.println("成员内部类的构造方法");

                  InnerClass ic=new InnerClass("lisi");//访问其他构造方法,内部类的对象

                  ic.id=11;//访问实例变量方式1

                  this.id=12;//访问实例变量方式2

                  id=13;//访问实例变量方式3,this和对象可以省略,

                  ic.Innermethod1();//访问实例方法1

                  this.Innermethod1();//访问实例方法2

                  Innermethod1();//访问实例方法3

                 

            }

            //public static void staticInnermethod(){}//报错,成员内部类不能有静态方法

            public InnerClass(String name){

                  System.out.println("成员内部类有参数的构造方法");

                  InnerClass ic1=new InnerClass();//访问其他构造方法,内部类的对象

                  ic1.id=11;//访问实例变量方式1

                  this.id=12;//访问实例变量方式2

                  id=13;//访问实例变量方式3,this和对象可以省略,

                  ic1.Innermethod1();//访问实例方法1

                  this.Innermethod1();//访问实例方法2

                  Innermethod1();//访问实例方法3

                 

                  new TestClass();//访问外部类

                  new TestClass().name="zj";//访问外部类实例变量方法1

                  TestClass.this.name="zj";//访问外部类实例变量方法2

                  new TestClass().lsp="sss";//访问外部类静态变量

                  TestClass.this.staticOutMethod();

                  TestClass.this.lsp="sss";

                  new TestClass().staticOutMethod();//访问外部类静态方法

                  //TestClass.this表示外部类这个当前类

                  new TestClass().outMethod();//访问外部类实例方法,方法1

                  TestClass.this.outMethod();//访问外部类实例方法,方法2

                  //还可以省略

                  outMethod();

                  name="zj";

            }

      }

}

public class OtherClass {

      public void otherMethod(){

            System.out.println("其他类的实例方法");

            //试着访问另一个类里面的内部类变量和方法

            //先访问外部类,再去内部类

            new TestClass();

            new TestClass().new InnerClass();

            //相当于先new外部类,TestClass tc=new TestClass();

            //在new内部类,TestClass.InnerClass tci=tc.new InnerClass();

            TestClass tc=new TestClass();

            TestClass.InnerClass tci=tc.new InnerClass();

            tci.id=999;

            tci.Innermethod1();

      }

      public static void staticOtherMethod(){

            System.out.println("其他类的静态方法");

            new TestClass();

            new TestClass().new InnerClass();

            //相当于先new外部类,TestClass tc=new TestClass();

            //在new内部类,TestClass.InnerClass tci=tc.new InnerClass();

            TestClass tc=new TestClass();

            TestClass.InnerClass tci=tc.new InnerClass();

            tci.id=999;

            tci.Innermethod1();

      }

      public  OtherClass(){

            System.out.println("其他类的构造方法");

            new TestClass();

            new TestClass().new InnerClass();

            //相当于先new外部类,TestClass tc=new TestClass();

            //在new内部类,TestClass.InnerClass tci=tc.new InnerClass();

            TestClass tc=new TestClass();

            TestClass.InnerClass tci=tc.new InnerClass();

            tci.id=999;

            tci.Innermethod1();

//         Innermethod1();不能省略

//         id=999;

      }

}

2.方法内部类

       定义在方法中的类,相当于局部变量

       基本格式:

public class TestClass {

      public TestClass(){

            //构造方法里面的内部类

            class InnerClass{

                  }

            }

      }

2.1 方法内部类用法

       (1)方法内部类(相当于局部变量),不能使用任何访问限制修饰符;

      (2)方法内部类可以有实例变量/方法,构造方法,不能有静态元素;

      (3)方法内部类可以访问本类的实例变量、实例方法、构造方法。【this/对象,也可以省略】;

      (4)方法内部类可以访问本方法的局部变量,直接变量名称访问。

             方法内部类访问本方法的局部变量时,方法内部类会默认是有final修饰符修饰本方法中的局部变量,final修饰的不能改值,局部变量也没有对象,不能创建对象。

      (5)外部类是不能访问到方法内部类。

             因为方法内部类相当于本方法中的局部变量,局部变量超出本方法访问不到。

例:

public class TestClass {

      int niu=222;//外部类实例变量

      static String ok="hao";//外部类类变量

      public TestClass(){

            System.out.println("外部类的构造方法");

            class InnerClass{

                  //构造方法里面的内部类

            }

      }

      public void shiMethod(){

            System.out.println("外部类的实例方法");

           

      }

      public static void staticShiMethod(){

            System.out.println("外部类的静态方法");

      }

      public void TestClass1(){

            int number=88;//本方法中的局部变量

            //实例方法里面的内部类

            class InnerClass{

                  int id=988;//实例变量

                  //static String name="hhh";报错

                  public void method1(){

                       System.out.println("方法内部类里面的实例方法");

                       new InnerClass();

                       new InnerClass().id=222;

                       new InnerClass().method1();

                       new InnerClass("ddd");

                       this.id=33;

                       this.method1();

                       id=33;

                       method1();

                       //访问方法内部类外面的本方法中的局部变量

                       //this.number=999; 错误,局部变量默认是final修饰的,不能改值

                       //局部变量也没有对象,不能创建对象

                       //所以直接变量名称访问

                       System.out.println(number);

                      

                  }

                  public InnerClass(){

                  System.out.println("方法内部类里面的构造方法1");

                       new InnerClass();

                       new InnerClass().id=222;

                       new InnerClass().method1();

                       new InnerClass("ddd");

                       this.id=33;

                       this.method1();

                       id=33;

                       method1();

                      

                  }

                  public InnerClass(String name){

                       System.out.println("方法内部类里面的构造方法2");

                      

                  }

            }

      }    

      public static void TestClass2(){

            //静态方法里面的内部类

            class InnerClass{

                  //方法内部类可以访问外部类的构造方法,实例方法/变量,类方法/变量

                  public void method1(){

                       new TestClass();

                       new TestClass().shiMethod();

                       new TestClass().niu=22;

                       new TestClass().staticShiMethod();

                       new TestClass().ok="ss";

                  }

                 

            }

      }

}

3.静态嵌套类

       相当于是java类中的静态变量

      格式:

public class TestClass {

      public static class InnerClass{

      }

}

      (1)静态嵌套类中可以有构造方法,实例变量/方法,类变量/方法;

     (2)静态嵌套类中构造方法/实例方法可以访问本静态嵌套类中的构造方法,实例变量/方法,类变量/方法;

    (3)静态内部类中的类方法可以访问本静态嵌套类中的构造方法,实例变量/方法【只能对象】,类变量/方法;

    (4)静态内部类中的构造方法/实例方法/类方法可以访问外部类的构造方法,实例变量/方法【只能对象】,类变量/方法;

    (5)静态嵌套类中不能有this.

    (6)外部类的构造方法/实例方法/类方法可以访问静态内部类中构造方法,实例变量/方法【只能对象】,类变量/方法;

    (7)其他类中可以访问静态嵌套类【new外部类类名.静态嵌套类名()】。注意访问限制修饰符。

例:

public class TestClass {

      public static int id=5;

      public static int num=7;

      public void method1(){

           

      }



      public static class InnerClass{

            //静态内部类的实例变量

            int id=23;

            //静态内部类的静态成员变量

            static int num=20;

            //静态内部类的构造方法

            public InnerClass(){

                  new InnerClass();

                  new InnerClass().id=1;

                  new InnerClass().num=1;

                  new InnerClass().method();

                  new InnerClass().staticMethod();

            }

            //静态内部类的实例方法

            public void method(){

                  new InnerClass();

                  new InnerClass().id=1;

                  new InnerClass().num=1;

                  new InnerClass().staticMethod();

            }

            //静态内部类的静态方法

            public static void staticMethod(){

                  new InnerClass();

                  new InnerClass().id=1;

                  new InnerClass().num=1;

                  new InnerClass().method();

                  new TestClass();

                  new TestClass().id=2;

                  new TestClass().num=2;

                  new TestClass().method1();

                  //this.

            }

      }

}

public class OtherClass {

      public void method(){

            //其他类中可以访问静态嵌套类【new 外部类类名.静态嵌套类名()】

            new TestClass.InnerClass();

           

      }

}

4.匿名内部类

       没有名字的java类,在不用创建出新类的情况下构建出当前类的子类构建的这个子类没有名字,所以叫匿名内部类

基本格式:

public class Person {

      public void method(){

            System.out.println("person的方法");

      }

}

测试类:

public class Main {

      public static void main(String[] args) {

      //不创建新类的情况下构建子类,叫匿名内部类

            Person per=new Person(){

                  public void method(){

                       System.out.println("person的方法重写");

                  }

            };

            per.method();

      }

}

      上述蓝色标记就是匿名内部类,就相当于Person类的子类,只是没有名字。

4.1 继承式的匿名内部类

这个匿名内部类的作用是在不创建新类的情况下创建父类的子类,实现继承关系。

例:

//抽象类

public abstract class Person {

      //抽象方法

      public abstract void method();

}

//普通类

public class PuTong{

      //实例方法参数是抽象对象

      public void method(Person per){

           

      }

}

测试类:

      public static void main(String[] args) {

            PuTong pt=new PuTong();

            //pt.method(per);此处的per是抽象类,需要创建对象

            //两种方式,上转型---子类对象赋值给父类对象

            //Person per1=new 子类对象;此处没有新建子类,所以可以使用匿名内部类

            Person per1=new Person(){

                       public  void method() {

                  }

            };

            pt.method(per1);

      }

}

4.2接口式的匿名内部类

这个匿名内部类的作用是在不创建新类的情况下创建接口的子类,实现多个接口。

当一个类中的方法参数是接口类型时,我们可以传递接口回调对象/子类对象,如果不想额外的创建一个接口的子类,这时我们使用匿名内部类也是可以的。

例:

//接口

public interface TestInterface {

      //抽象方法

      public abstract void method();



}

//普通类

public class PuTong{

      //实例方法参数是抽象对象

      public void method(TestInterface tsi){

           

      }

}

测试类:
public class Main {



      public static void main(String[] args) {

            PuTong pt=new PuTong();

            //pt.method(tsi);此处的tsi是接口类,需要创建对象

            //两种方式,接口回调对象---子类对象赋值给父类对象

            //Person per1=new 子类对象;此处没有新建子类,所以可以使用匿名内部类

            TestInterface tsi1=new TestInterface(){

                       public  void method() {

                      

                  }

                 

            };

            pt.method(tsi1);

           

      }

}

4.3 匿名内部类优缺点

        优点:避免创建额外的独立子类。

        缺点:不易理解,不易阅读。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java-请多指教

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值