[Java基础篇]Java内部类的剖析

一、什么是内部类?

可以将一个类的定义放在另一个类的定义内部,这就是内部类
为什么要用内部类?
内部类方法可以访问该类中定义所在的作用域中的数据,包括私有数据
内部类可以对同一个包中的其他类隐藏起来。
当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。
什么时候用到内部类?
当描述事物时,若一个事物内部还包含其他事物,就可以使用内部类这种结构。如,汽车类Car中包含发动机类Engine使用内部类的好处:
内部类可以很好的实现隐藏,一般非内部类,时不允许有private与protected权限的,但内部类可以。
内部类拥有外围类的所有元素的访问权限。
可以实现多重继承。
可以避免修改接口而实现同一个类中两种同名方法的调用。
缺点: 内部类的结构复杂。

二、创建内部类

在Java中内部类主要分为成员内部类、局部内部类、匿名内部类、静态内部类。

///创建非静态内部类对象格式:
外部类名.内部类名 对象名 = new 外部类().new 内部类();
Car.Engine engine = new Car.new Engine();

///创建静态内部类的格式:
外部类名.内部类名 对象名 = new 外部类.内部类;
Car.Engine engine = c.Engine();

///在外部类的方法中创建内部类,就像普通对象一样直接创建
 Engine engine = new Engine();
2.1 成员内部类

成员内部类是最普通的内部类,它是外围类的一个成员,所以它是可以无限制的访问外围类的所有属性和方法,即使是private。但是外围类要访问内部类的成员属性和方法需要通过内部类实例来访问。

注意:
在成员内部类中,不能存在任何static的变量和方法;
成员内部类是依附于外部类的,所以只有先创建外围类才能构创建内部类。

class Car{
      private boolean run = true;
      class Engine{
          public void runEmgine(){
              if(run) System.out.println("发动机启动!");
              else System.out.println("发动机坏了!");
          }
      }
      ///当内部类的构造方法无参数时,推荐使用getXxx()来获取成员内部类
      public Engine getEngine(){
          return new Engine();
      } 
}
public class Main {
    public static void main(String [] args){
       Car c = new Car();
      Car.Engine engine = c.new Engine();
     /// Car.Engine engine = c.getEngine();
       engine.runEmgine();
    }
}

2.2 局部内部类(方法内部类)

局部内部类,是嵌套在方法内,且只能作用于方法内的内部类。局部内部类不能使用public、protected、private和static修饰符(由于局部内部类不能在外围类的方法以外的地方使用

class Car{
      private boolean run = true;
      public void Method() {
          class Engine {
              public void runEmgine() {
                  if (run) System.out.println("发动机启动!");
                  else System.out.println("发动机坏了!");
              }
          }
          new Engine().runEmgine();
      }
}
public class Main {
    public static void main(String [] args){
       Car c = new Car();
       c.Method();
    }
}
2.3 静态内部类

使用static修饰的内部类为静态内部类,静态内部类与非静态内部类存在一个最大的区别,内部类编译后会隐含地保存着一个引用,该引用是指向创建它的外围类内,但是静态内部类没有。

静态内部类的创建是不需要依赖外围类的。
静态内部类不能使用外围类的非static成员变量和方法。

class Car{
      public static String name = "长安汽车" ;
          static class Engine {
              public void EngineMethod() {
                  System.out.println("这汽车发动机为" + name + "制造的");
              }
          }
          public  void CarMethod(){
              new Engine().EngineMethod();
          }
}
public class Main {
    public static void main(String [] args){
       Car c = new Car();
       c.CarMethod();
    }
}

2.4 匿名内部类

匿名内部类是内部类的简化写法。
它的本质是一个带具体实现的父类或者父接口的匿名的子类对象。在开发中,最常用的内部类就是匿名内部类了。
匿名内部类的作用:能简化接口的创建以及实现的步骤。
在这里插入图片描述

匿名内部类的前提:必须继承一个父类或者实现一个父接口。

实现方式一:

interface function{
    public abstract void run();
}

public class Main {
    public static void main(String [] args) {
        ///等号右边:定义并创建该接口的子类对象
        ///等号左边:多态,接口类型引用类型指向子类对象
        function f = new function() {
            @Override
            public void run() {
                System.out.println("发动机启动!");
            }
        };
        f.run();
    }

      public static void showRun(function f){
            f.run();
    }
}

实现方式二:

interface function{
    public abstract void run();
}

public class Main {
    public static void main(String [] args) {
    ///创建匿名内部类,直接传递给showRun(function f)
        showRun(new function() {
            @Override
            public void run() {
                System.out.println("发动机启动了!!!");
            }
        });
    }

      public static void showRun(function f){
            f.run();
    }
}

使用匿名内部类,我们要注意:
匿名内部类是没有访问修饰符的
当所在的方法的形参需要被匿名的内部类使用,那么这个形参就必须为final。
匿名内部类没有构造方法,因为本身没有名字。不能定义静态成员。

三、内部类与外围类之间的关系

内部类与外围类是两个独立完整的类,在运行是生成各自的.class文件。
内部类相当于外围类的一个成员变量的位置,可以使用任意访问控制符。
内部类可以随意访问外围类的成员方法与成员变量(不受访问控制符的影响),但内部类不可以访问内部类的成员变量与成员方法。

1. 编译器自动为内部类添加一个成员变量,这个成员变量的类型和外围类的类型相同,这个成员变量就是指向外围类对象(this)的引用。
2. 编译器自动为内部类的构造方法添加一个参数,参数的类型是外围类的类型,在构造方法内部使用这个参数为内部类中添加的成员变量赋值。
3. 在调用内部类的构造函数初始化内部类对象时,会默认传入外围类的引用

要调用内部类的方法只能通过实例内部类对象来调用。

通过.this来在内部类中引用其外围类
一个外围类中的内部类对象,是与这个外围类的对象存在着一个链接的依存关系的,那么我们是不是可以在内部类中显式地调起这个外围类地对象呢?答案是肯定的。如果我们在内部类中生成对于外围类对象的引用,可以使用外围类的名字后面紧跟.this,这样产生的引用自动对地具有正确的类型,这一点在编译期就会被知晓并受到检查,因此没有任何运行时的开销。

public class Car {
    void getName(){
      System.out.println("这是长安汽车!");
    }
    class Engine {
        public Car runEmgine() {
            return Car.this;///引用外围类
        }
    }
    public Engine Engine(){
        return new Engine();
    }
    public static void main(String [] args){
        Car car = new Car();
        Car.Engine engine = car.Engine();
        engine.runEmgine().getName();
    }
}

参考资料

1.https://www.cnblogs.com/chenssy/p/3388487.html
2.https://blog.csdn.net/qq_43646059/article/details/104441947?utm_source=app

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ava实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),可运行高分资源 Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现
C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。下面详细介绍C语言的基本概念和语法。 1. 变量和数据类型 在C语言中,变量用于存储数据,数据类型用于定义变量的类型和范围。C语言支持多种数据类型,包括基本数据类型(如int、float、char等)和复合数据类型(如结构体、联合等)。 2. 运算符 C语言中常用的运算符包括算术运算符(如+、、、/等)、关系运算符(如==、!=、、=、<、<=等)、逻辑运算符(如&&、||、!等)。此外,还有位运算符(如&、|、^等)和指针运算符(如、等)。 3. 控制结构 C语言中常用的控制结构包括if语句、循环语句(如for、while等)和switch语句。通过这些控制结构,可以实现程序的分支、循环和多路选择等功能。 4. 函数 函数是C语言中用于封装代码的单元,可以实现代码的复用和模块化。C语言中定义函数使用关键字“void”或返回值类型(如int、float等),并通过“{”和“}”括起来的代码块来实现函数的功能。 5. 指针 指针是C语言中用于存储变量地址的变量。通过指针,可以实现对内存的间接访问和修改。C语言中定义指针使用星号()符号,指向数组、字符串和结构体等数据结构时,还需要注意数组名和字符串常量的特殊性质。 6. 数组和字符串 数组是C语言中用于存储同类型数据的结构,可以通过索引访问和修改数组中的元素。字符串是C语言中用于存储文本数据的特殊类型,通常以字符串常量的形式出现,用双引号("...")括起来,末尾自动添加'\0'字符。 7. 结构体和联合 结构体和联合是C语言中用于存储不同类型数据的复合数据类型。结构体由多个成员组成,每个成员可以是不同的数据类型;联合由多个变量组成,它们共用同一块内存空间。通过结构体和联合,可以实现数据的封装和抽象。 8. 文件操作 C语言中通过文件操作函数(如fopen、fclose、fread、fwrite等)实现对文件的读写操作。文件操作函数通常返回文件指针,用于表示打开的文件。通过文件指针,可以进行文件的定位、读写等操作。 总之,C语言是一种功能强大、灵活高效的编程语言,广泛应用于各种领域。掌握C语言的基本语法和数据结构,可以为编程学习和实践打下坚实的基础
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值