一、简介

描述:

  • 很多时候我们创建类的对象的时候并不需要使用很多次,每次只使用一次,这个时候我们就可以使用内部类了。
  • 内部类不是在一个java源文件中编写两个平行的类,而是在一个类的内部再定义另外一个类。 我们可以把外边的类称为外部类,在其内部编写的类称为内部类。

分类:

  1. 成员内部类
  2. 静态内部类
  3. 局部内部类
  4. 匿名内部类

内部类通用用法:

  • 要想访问内部类中的内容,必须通过外部类或外部类对象
  • 内部类可以访问外部类的所有访问权限的属性和方法,包括私有的成员变量、方法。原理就是在通过外部类对象实例化内部类对象时,外部类对象把自己的引用传进了内部类,使内部类可以用通过'外部类名.this'去调用外部类的属性和方法。一般都是隐式调用了,但是当内部类中有属性或者方法名和外部类中的属性或方法名相同的时候,就需要通过显式调用'外部类名.this.外部类属性名'了。

二、成员内部类

描述:

  • 成员内部类又叫实例内部类、非静态内部类。
  • 一个类在另一个类的内部,那么想要使用这个内部类,就必须先要有外部类的一个实例对象,然后在通过该对象去使用内部类

注意:

  • 成员内部类中可以访问外部类的所有属性和方法,包括私有的成员变量、方法。
  • 成员内部类中不能写静态的属性和方法
  • 实例化内部类,首先需要实例化外部类,通过外部类去调用内部类
  • 如果内部类中的变量名和外部类的成员变量名一样,在内部类中,要通过'外部类名.this.外部类属性名'来访问外部类属性,通过'this.内部类属性名'来访问内部类属性

示例:

class Outer {
private int id;
private String name = "outer"; public void out() {
System.out.println("这是外部类方法");
} class Inner {
private int id = 8; public void in() {
System.out.println("这是内部类方法");
} public void test() {
System.out.print(name + " " + Outer.this.id + " " + id);
}
}
} public class Test {
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.test();//outer 0 8
}
}

三、静态内部类

描述:

  • 使用'static'修饰的内部类就叫静态内部类
  • 静态内部类是外部类的静态成员,从属于外部类,不从属于外部类对象。

特点:

  • 静态内部类能够直接被外部类给实例化,不需要使用外部类对象。
  • 静态内部类中可以声明静态方法和静态变量
  • 静态内部类中没有外部类对象的引用,所以不能使用外部类的非静态属性和方法

示例:

public class Test {
private String name;
private static int age; public void run() {
} public static void go() {
} private static class StaticInnerClass {
private String name;
private static int age; public void test1(String name) {
System.out.println(name + " " + this.name + " " + StaticInnerClass.age + " " + Test.age);
/*
静态内部类不能访问外部类非静态属性
System.out.println(Test.this.name);
*/
Test.go();
/*
静态类不能访问非静态方法
Test.this.run();
*/
} public static void test2(String name) {
/* 内部类的静态方法只能访问自己和外部类的静态属性和方法 */
System.out.print(name + " " + StaticInnerClass.age + " " + Test.age);
/*
内部类的静态方法不能访问外部类的非静态属性
System.out.println(Test.this.name);
*/
/*
内部类的静态方法里面连自己类的非静态属性都不能访问
System.out.println(this.name);
*/
Test.go();
/*
内部类的静态方法不能访问非静态方法
Test.this.run();
*/
}
} /* 外部类访问静态内部类 */
public static void main(String[] args) {
/* 静态的内部类不需要依赖外部类,所以不用new外部类对象 */
StaticInnerClass sic = new StaticInnerClass();
/* 内部类对象调用内部类成员变量和成员方法 */
sic.name = "张三";
sic.test1("李四");//李四 张三 0 0
/* 内部类调用内部类静态变量和静态方法 */
StaticInnerClass.age = 10;
StaticInnerClass.test2("王五");//王五 10 0
}
}

四、局部内部类

描述:

  • 局部内部类是在方法内部声明的类
  • 局部内部类只能在所在的方法中使用,生命周期相当于一个局部变量,只能在方法体里。
  • 局部内部类的作用跟在成员内部类差不多,也可以访问所在外部类的成员变量及方法。

注意:

  • 局部内部类不能通过外部类对象直接实例化,而是在方法中实例化出自己来,然后通过内部类对象调用自己类中的方法。
  • 局部内部类中如果要访问该内部类所在方法中的局部变量,那么这个局部变量就必须是'final'修饰的。'final'修饰的变量会变为常量,在常量池中放着。如果不变为常量,当局部内部类被实例化后,方法弹栈,局部变量随着跟着消失,这个时候局部内部类对象想去调用该局部变量,就会出错,因为该局部变量已经没了。当局部变量变为常量后,就会将其加入常量池中,即使方法弹栈了,该局部变量还在常量池中呆着,局部内部类也就是够调用。所以局部内部类想要调用局部变量时,需要使用'final'修饰,不使用,编译都通不过。

示例:

public class Test {
private String name;
private static int age; public void run() {
} public static void go() {
} public void test() {
final String myName = "王五";
/* 局部内部类要定义在方法中 */
class LocalInnerClass {
private String name;
/*
不能定义静态属性
private static int age;
*/
public void test(String name) {
System.out.println(name + " " + this.name + " " + myName + " " + Test.this.name);
Test.this.run();
Test.go();
}
} LocalInnerClass lic = new LocalInnerClass();
lic.name = "张三";
lic.test("李四");//李四 张三 王五 null
} public static void main(String[] args) {
new Test().test();
}
}

五、匿名内部类

描述:

  • 匿名内部类是最常用的一种内部类。
  • 匿名内部类是只会使用一次的类。那么就不需要先定义一个类,而是等到需要用的时候,再临时实现并使用这个类。
  • 匿名内部类需要依托于其他类或者接口来创建。如果依托的是类,那么创建出来的匿名内部类就默认是这个类的子类;如果依托的是接口,那么创建出来的匿名内部类就默认是这个接口的实现类。
  • 匿名内部类的声明必须是在使用'new'关键字的时候。匿名内部类的声明及创建对象必须一气呵成,并且之后不能反复使用,因为没有名字。

注意:

  • 匿名内部类除了依托的类或接口之外,不能指定继承或者实现其他类或接口,同时也不能被其他类所继承,因为没有名字。
  • 匿名内部类中,我们不能写出其构造器,因为没有名字。
  • 匿名内部类中,除了重写或实现依托的类或接口的方法外,一般不会再写其他独有的方法,因为从外部不能直接调用到(间接是调用到的)。

语法:

new Class(){
/* 重写类里的方法,或者实现类或接口中的抽象方法。 */
}

示例:

interface Person {
public void say();
} public class Test {
public static void main(String[] args) {
/*
new Class(){}的作用就是将接口给实现了,只不过这里实现该接口的是一个匿名类,也就是说这个类没名字,只能使用这一次。
我们知道了这是一个类,将其new出来,就能获得一个实现了Person接口的类的实例对象,通过该实例对象,就能调用该类中的方法了。
因为该匿名类是在一个类中实现的,所以叫其匿名内部类。
*/
new Person() {
public void say() {
System.out.println("实现了Person接口的方法");
}
}.say();//实现了Person接口的方法
}
}

Java基本概念:内部类的更多相关文章

  1. JAVA 第二天 内部类

    package com.company; /** * Created by Administrator on 2016/8/23. */ public class Outter {//生成的字节码文件 ...

  2. 【转】Java中的内部类和匿名类

       Java内部类(Inner Class),类似的概念在C++里也有,那就是嵌套类(Nested Class),乍看上去内部类似乎有些多余,它的用处对于初学者来说可能并不是那么显著,但是随着对它的 ...

  3. Java中的内部类怎么用

    一.为什么需要内部类?java内部类有什么好处?为什么需要内部类? 首先举一个简单的例子,如果你想实现一个接口,但是这个接口中的一个方法和你构想的这个类中的一个方法的名称,参数相同,你应该怎么办?这时 ...

  4. [java] 深入理解内部类: inner-classes

    [java] 深入理解内部类: inner-classes // */ // ]]>   [java] 深入理解内部类: inner-classes Table of Contents 1 简介 ...

  5. Java中的内部类(成员内部类、静态内部类、局部内部类、匿名内部类)

    Java中的内部类(成员内部类.静态内部类.局部内部类.匿名内部类) 神话丿小王子的博客主页 我们先看这样一段话:人是由大脑.肢体.器官等身体结果组成.而组成我们人体的心脏它也有自己的属性和行为(血液 ...

  6. java基础之 内部类

    Java中的内部类共分为四种: 静态内部类static inner class (also called nested class) 成员内部类member inner class 局部内部类loca ...

  7. java 笔记(2) —— 内部类的作用

    一.内部类简介 个人觉得内部类没多少研究价值,GUI中的事件响应算是非常典型的应用了. Java内部类其实在J2EE编程中使用较少,不过在窗口应用编程中特别常见,主要用来事件的处理.其实,做非GUI编 ...

  8. Java基础(53):内部类(转)

    java中的内部类总结 内部类不是很好理解,但说白了其实也就是一个类中还包含着另外一个类 如同一个人是由大脑.肢体.器官等身体结果组成,而内部类相当于其中的某个器官之一,例如心脏:它也有自己的属性和行 ...

  9. Java多线程概念简介 多线程中篇(一)

    Java的线程与操作系统的线程   在线程的相关介绍中,有讲到“线程的实现”分为三种:内核支持,用户级以及两者混合.(这只是一种简要的分类) Java线程在JDK1.2之前,是用户线程实现的 而在JD ...

  10. -1-5 java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait(),notify(),notifyAll()等方法都定义在Object类中

     本文关键词: java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁  sleep()和wait()方法的区别 为什么wait( ...

随机推荐

  1. 【noi 2.6_4982】踩方格(DP)

    题意:一个无限大的方格矩阵,能向北.东.西三个方向走.问走N步共有多少种不同的方案. 解法: f[i]表示走 i 格的方案数. 状态转移方程推导如下--设l[i],r[i],u[i]分别为第 i 步向 ...

  2. Codeforces Round #582 (Div. 3) A. Chips Moving

    传送门 题解: 给你n个数的坐标,你需要把他们移动到一个位置,有两种移动方式 1.向左或者右移动2 2.向左或者右移动1,但是耗费1 求最小耗费 题解: 很简单就可以想到,看一下偶数坐标多还是奇数坐标 ...

  3. 使用eclipse搭建第一个java web应用

    一. 首先是eclipse得下载,你要下载Eclipse IDE for Java EE这种类型的,我之前下载的Eclipse IDE for Enterprise Java Developers是官 ...

  4. Educational Codeforces Round 95 (Rated for Div. 2) B. Negative Prefixes (贪心,构造)

    题意:给你一串长度为\(n\)的序列,有的位置被锁上了,你可以对没锁的位置上的元素任意排序,使得最后一个\(\le0\)的前缀和的位置最小,求重新排序后的序列. 题解:贪心,将所有能动的位置从大到小排 ...

  5. Bing壁纸-20200416

  6. OpenStack Train版-4.安装placement放置服务

    安装placement放置服务 创建placement数据库 mysql -uroot CREATE DATABASE placement; GRANT ALL PRIVILEGES ON place ...

  7. LINUX - 文件读写缓存

    遇到一个进程core掉后日志打印不出来的问题: 参考如下: [引用] 只有正常退出,才能做到flush.否则将写失败. 之后有百度了下中文资料,发现同样的结论. "fflush库函数的作用是 ...

  8. Python_变量作用域与修改

    引用全局变量,不需要golbal声明,修改全局变量,需要使用global声明,特别地,列表.字典等如果只是修改其中元素的值(而不是整体赋值的形式),可以直接使用全局变量,不需要global声明. 参考 ...

  9. 一句话木马的简单例子 网站webshell & 远程连接

    一  概述 本地 kail  linux 目标 windows nt 服务器 二 过程 首先编写一句话木马  index.php 一句话木马的原理就是把C=xxx 字符串当成php语句执行 注意这里用 ...

  10. axios增加自定义headers,页面上出现,服务端收不到

    问题 axios增加自定义headers,页面上出现,服务端收不到 原因 vue-cli起的服务是用node-http-proxy中间件处理的 默认是只有几个常用的header,自定义header是直 ...