外部类:单独定义的一个类,不在其他类的内部,只能用 public 和 缺省 权限修饰符

内部类:在类的内部再定义一个类,根据内部类的定义位置和修饰符的不同,可以分为:

1. 成员内部类:

语法格式:

[修饰符] class 外部类{
    [修饰符] class 内部类{    }
}

成员内部类特点:

1.不能使用static关键字,但是可以使用 static final关键字定义常量

2.内部类可以直接访问外部类的成员(包括私有成员)

3.内部类如果想要调用外部类的方法,需要使用 `外部类名.this.外部方法名`

4.可以使用final修饰内部类,表示不能被继承

5.编译以后也会有自己独立的字节码文件, Outer$Inner.class

6.外部函数的static成员的,不允许访问成员的内部类

7.可以在外部类里创建内部类对象,然后在通过方法返回,同事,也可以使用 new Outer().new Inner() 在外部直接访问内部类

public class Test {public static void main(String[] args) {// 直接使用 new Outer().new Inner() 方法创建一个Inner对象Outer.Inner inner1 = new Outer().new Inner();  // 创建一个 Outer 对象,//再调用 Outer 对象的 getInner方法,在getInner方法里创建并返回 Inner 对象Outer.Inner inner2 = new Outer().getInner();}
}
class Outer {int age = 19;private String name = "jack";private void test() {System.out.println("我是Outer类里的test方法");}class Inner {  // 可以把 Inner 想象成为和 age / name一样,只不过它的数据类型是class// static int a = 10;  报错,不能使用 staticstatic final int b = 1;  // 可以使用 static final 定义常量private void test() {System.out.println("我是Inner类里的test方法");}public void demo() {// 内部类可以直接访问外部类的成员,包括私有成员。System.out.println(name);this.test();  // 等价于 test() 调用的是内部类的test方法Outer.this.test(); // 需要使用 Outer.this 调用外部类的 test 方法}}public static void foo() {// Inner inner = new Inner();  报错!外部static成员不允许访问非静态内部类}public Inner getInner() {return new Inner();}
}

示例:


//成员内部类
public class MemberOuter {private int x = 10;private static int m = 5;public final class MemberInner {private int a = 2;// private static int b = 4;private static final int c = 5;int x = 3;public void demo() {int x = 1;System.out.println("MemberInner类demo方法里的x = " + x);System.out.println("MemberInner类demo方法里的this.x = " + this.x);System.out.println("MemberInner类demo方法里的MemberOuter.this.x = " + MemberOuter.this.x);System.out.println(m);xxx();}}public void test() {MemberInner inner = new MemberInner();inner.demo();}public static void xxx() {}
}

public class InnerDemo {public static void main(String[] args) {//创建成员内部类的对象必须先创建外部类对象!//创建成员内部类对象必须要先创建外部类对象//方式a:在外部类的内部创建对象并使用//方式b: 也可以直接创建一个成员内部类对象(和权限修饰符有关)//外部类名.内部类名  变量名 = 外部类对象名.new 成员内部类名();MemberOuter memberOuter = new MemberOuter();memberOuter.test();// MemberOuter.MemberInner memberInner = memberOuter.new MemberInner();MemberOuter.MemberInner memberInner = new MemberOuter().new MemberInner();}
}

总结:

成员内部类:

1. 和成员变量一样,可以使用全部的四种权限修饰符和final修饰符

2. 在成员内部类里可以访问外部类的所有成员变量,调用所有方法,包括静态的。

3.在成员内部类里可以定义非静态成员变量,也可以使用static final 定义静态成员常量,但是不能使用static定义静态变量

4. 调用成员内部类的方法和访问成员内部类里变量,需要先创建成员内部类对象

创建成员内部类对象必须要先创建外部类对象

a.在外部类的内部创建对象并使用

MemberOuter memberOuter = new MemberOuter();
memberOuter.test();

b.也可以直接创建一个成员内部类对象(和权限修饰符有关)

外部类名.内部类名  变量名 = 外部类对象名.new 成员内部类名();

MemberOuter.MemberInner memberInner = new MemberOuter().new MemberInner();

5. 在成员内部类里出现  内部类成员变量、内部类局部变量、外部类成员变量同名的情况

  • 在方法里直接访问,访问的是局部变量
  • 使用 this.变量名 访问内部类的成员变量
  • 使用  外部类名.this.变量名  访问外部类的成员变量

6. 成员内部类编译以后也会生成一个 .class文件,文件名是  外部类名$内部类名.class。

2.静态内部类

静态内部类也被成为 嵌套类,静态内部类不会持有外部类对象的引用

语法格式:

[修饰符] class 外部类{    
    [其他修饰符] static class 内部类{    }
}

静态内部类特点:

1. 使用static关键字修饰

2. 在静态内部类里,可以使用static关键字定义静态成员

3.只能访问外部的静态成员,不能访问外部的非静态成员

4. 外部类可以通过  静态内部类名.静态成员名  访问静态内部类的静态成员

class Outer {int age = 19;static String type = "outer";static class Inner {  // 需要使用 static 关键字static int x = 1;  // 能够定义静态变量public static void test() {// 只能访问外部的静态变量,不能访问非静态变量// System.out.println(age);System.out.println(type);}}public void  demo() {// 外部类可以直接通过 内部类.静态变量名,不需要创建对象System.out.println(Inner.x);  }
}

示例:

public class StaticOuter {private int x = 10;private static int m = 3;public static final class StaticInner {private int a = 5;private static int b = 7;private int x = 1;private static int m = 6;public void test() {// System.out.println(x);// foo();int x = 2;int m = 9;System.out.println("StaticInner类test方法里 x = " + x);  // 2System.out.println("StaticInner类test方法里 x = " + this.x);  // 1System.out.println("StaticInner类test方法里 m = " + m);  // 9System.out.println("StaticInner类test方法里 StatiInner.m = " + StaticInner.m);  // 6System.out.println("StaticInner类test方法里 StaticOuter.m = " + StaticOuter.m);  // 3demo();}public static void bar() {// System.out.println(x);}}public static void demo() {}public void foo() {}
}
public class InnerDemo {public static void main(String[] args) {MemberOuter memberOuter = new MemberOuter();memberOuter.test();// MemberOuter.MemberInner memberInner = memberOuter.new MemberInner();MemberOuter.MemberInner memberInner = new MemberOuter().new MemberInner();StaticOuter.StaticInner staticInner = new StaticOuter.StaticInner();StaticOuter.StaticInner.bar();}
}

总结:

静态内部类:

1. 定义的位置和成员内部类的位置一样,使用static关键字修饰

语法上可以理解为 成员内部类前面使用static修饰

2. 可以使用 四种权限修饰符和 final修饰符

3. 不能访问外部类的非静态成员变量,可以访问外部类的静态成员变量

总结:静态只能访问静态的。不能访问非静态的

4. 可以定义  非静态成员变量,也可以定义静态成员变量

5. 创建静态内部类对象,可以不创建外部类对象

静态内部类就像是一个单独的类,只不过借用了外部类的命名空间

StaticOuter.StaticInner staticInner = new StaticOuter.StaticInner();

6. 也会生成独立的 .class文件,文件名是  外部类名.静态内部类名

3. 局部内部类

局部内部类定义在外部类的方法中,就像局部变量一样,并不是外部类的成员。

局部内部类在方法外是无法访问到的,但它的实例可以从方法中返回,并且实例在不在被引用之前会一直存在。

语法格式:

[修饰符] class 外部类{
    [修饰符] 返回值类型  方法名([形参列表]){
            [final/abstract] class 内部类{
        }
    }    
}

局部内部类的特点:

1. 定义在类的某个方法里,而不是直接定义在类里

2. 局部内部类前面不能有权限修饰符

3. 局部内部类里不能使用static声明变量

4. 局部内部类访问外部类的静态成员

5. 如果这个局部内部类所在的方法是静态的,它无法访问外部类的非静态成员

6. 局部内部类可以访问外部函数的局部变量,但 这个局部变量必须要非final修饰。JDK8以后,final可以省略

class Outer {int age = 19;static int m = 10;public void test() {// final String y = "good";String y = "good";  // JDK8 以后,final可以省略class Inner {  // 定义在外部类的某个方法里// static int a = 10; 不能定义静态变量!  private  void demo() {System.out.println(age);// 不能修改外部函数的局部变量// y = 'yes';// 只能访问被 final 修饰的外部函数的局部变量// JDK8 以后,如果外部函数的局部变量没有加 final,编译器会自动加 finalSystem.out.println(y);}}Inner inner = new Inner();inner.demo();}
}

示例:

public class LocalOuter {private int x = 6;public void test() {int x = 10;int y = 0;class LocalInner {private int a = 1;// private static int b = 2;private static final int c = 3;private int x = 5;public void demo() {int x = 1;System.out.println("demo方法里的x = " + x);  // 1System.out.println("demo方法里的this.x = " + this.x);  // 5System.out.println("外部类里的成员变量x = " + LocalOuter.this.x); // 6// 如果出现同名的情况,无法再访问 方法里的同名局部变量System.out.println(y);}}// y = 3; 局部变量 y 被局部内部类使用了,不能再修改了LocalInner localInner = new LocalInner();localInner.demo();}
}

总结:

局部内部类:

1. 定义在一个方法里,和局部变量 定义的位置相同

2. 不能使用任何的权限修饰符和 static修饰符

3. 可以定义非静态成员变量、静态成员变量  但不能定义静态变量

4. 局部内部类可以访问所在方法里的局部变量

但是如果出现同名的情况

访问 局部内部类里的局部变量直接写变量名

访问 局部内部类里的成员变量使用 this.变量名

访问 外部类里的成员变量,使用 外部类名.this.变量名

不能访问 局部内部类所在方法的同名局部 变量

5. 被局部内部类访问的 局部变量,需要被final修饰。JDK8以后,final可以省略

6. 局部内部类只能在声明它的那个方法里使用

7. 生成独立的.class文件,文件名是 外部类名.编号局部内部名

4. 匿名内部类

用来创建  一个接口或者抽象类  对象

(抽象类或者接口  本不可以直接创建对象,可使用匿名内部类方法直接创建)

语法格式:

new 父类名或者接口名(){   
    // 方法重写
    @Override 
    public void method() {
        // 执行语句
    }
};

匿名内部类特点:

1. 匿名内部类就是一种特殊的局部内部类,只不过没有名称而已,基本特点和局部内部类一致

2. 匿名内部类不能有构造器,匿名内部类没有类名,肯定无法声明构造器

3. 匿名内部类的前提是,这个内部类必须要继承自一个父类或者父接口

4. 匿名内部类是接口的一种常见简化写法,也是我们开发中最常使用的一种内部类。它的本质是一个实现类父类或者父类接口具体方法的一个匿名对象

abstract class Animal{abstract void shout();
}class Demo{public void demo(){Animal animal = new Animal() {@Overridevoid shout() {System.out.println("动物在叫");}};}
}

示例:

AInterface接口

public interface AInterface {void test();
}

用AInterface直接创建类,用匿名内部类方法

public class AnonymousDemo {public static void main(String[] args) {AnonymousDemo x = new AnonymousDemo();x.demo();}public void demo(){/*class Son implements AInterface{@Overridepublic void test() {}}//Son s = new Son();s.test();new Son().test();*///匿名内部类AInterface a = new AInterface() {@Overridepublic void test() {System.out.println("helloA");}};//对象a的类型不是AInterface类型,而是AInterface类型的子类!这个类没有名字a.test();System.out.println(a.getClass());//匿名内部类 + 匿名对象 :  可以将一个方法当作另一个方法的参数使用new AInterface() {@Overridepublic void test() {System.out.println("helloB");}}.test();}
}

匿名内部类的作用:可以将一个方法当作另一个方法的参数使用

public class AnonymousTest {public static void main(String[] args) {AnonymousTest test = new AnonymousTest();Calculator c = new Calculator() {@Overridepublic int doCalculator(int a, int b) {return a+b;}};int x = test.calculate(1,9,c);//等价int y = test.calculate(1, 9, new Calculator() {@Overridepublic int doCalculator(int a, int b) {return a+b;}});System.out.println(x);}public int calculate(int a,int b,Calculator calculator){return calculator.doCalculator(a, b);}
}interface Calculator{int doCalculator(int a,int b);
}

内部类(成员内部类、局部内部类、匿名内部类、静态内部类)相关推荐

  1. java 内部类 返回值_Java基础第10天+形式参数和返回值的问题、包、导包、权限修饰符、常见的修饰符、内部类(局部内部类,成员内部类,匿名内部类)...

    1:形式参数和返回值的问题(理解) (1)形式参数: 类名:需要该类的对象 抽象类名:需要该类的子类对象 接口名:需要该接口的实现类对象 (2)返回值类型: 类名:返回的是该类的对象 抽象类名:返回的 ...

  2. 【java笔记】成员内部类 局部内部类 匿名内部类

    内部类:一个类的内部包含另一个类 如:身体和心脏的关系,汽车和发动机的关系 分类:(1)成员内部类 (2)局部内部类(包含匿名内部类) 成员内部类: 定义格式:修饰符 class 外部类名称{ 修饰符 ...

  3. Java 内部类、局部内部类、静态内部类使用

    1.上代码: //局部内部类.静态内部类.匿名类接口仅仅解决了多继承的部分问题,内部类有效实现了多重继承package ClassN1;public final class InnerClass {p ...

  4. 外部类、内部类、局部内部类、匿名类(Java)

    外部类.内部类.局部内部类.匿名类(Java) 代码一: public class Application {public static void main(String[] args) {Outer ...

  5. 内部类(成员内部类+局部内部类+静态内部类+匿名内部类)

    内部类的定义:在java中,允许在一个类的内部定义类,称为内部类,这个内部类所在的类称为外部类.内部类定义在外部内的内部,通常只服务于外部类,对于其他外部是不具备可见性的. 内部类应用场景:1.当某个 ...

  6. Java的(((φ(◎ロ◎;)φ))) 实例(成 员)内部类、局部内部类、匿名内部类和静态内部类。

    关于让你晕头的Java类 总结 2.细枝末节 小试牛刀 Biu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~pia! # 梳理一下 # 前言 Java里有各种各样 ...

  7. java局部内部类_Java 局部内部类、匿名内部类详解

    外部类与内部类 众所周知,每个java文件必须有一个与这个java文件同名的外部类,这个外部类可以是public或default的.而除了这个同名外部类,还可以有与这个同名外部类平级的其他外部类,但它 ...

  8. JAVA基础——内部类(成员内部类、静态内部类、局部内部类、匿名内部类)

    成员内部类 静态内部类 局部内部类 匿名内部类 1.成员内部类(实例内部类.非静态内部类) 成员内部类中不能写静态属性和方法 实例化内部类,首先需要实例化外部类,通过外部类去调用内部类   作用 要想 ...

  9. java 局部内部类常用么_Java中的内部类

    一.内部类概述 在一个类的内部定义一个类.在 A 类中定义 类 B.B 类就被叫做 A 的内部类.A 类就是 B 的外部类. 二.内部类的种类 内部类分为:成员内部类.静态内部类.局部内部类.匿名内部 ...

  10. 第三次学JAVA再学不好就吃翔(part43)--局部内部类访问局部变量

    学习笔记,仅供参考 面向对象 局部内部类访问局部变量 啥叫局部内部类? 局部内部类是指在方法中定义的内部类. 举个例子(访问局部内部类) 局部内部类: class InnerTest1 {public ...

最新文章

  1. 【设计模式】外观模式 ( 概念 | 适用场景 | 优缺点 | 代码示例 )
  2. 零基础前端入门,真正难在哪里?简说编程思想和逻辑思维
  3. P3545HUR-Warehouse StoreP4053建筑抢修(反悔贪心、堆)
  4. Redis集群版在Java中的应用
  5. ES6对于数组的扩展
  6. ScreenPad 是什么
  7. WebSphere中连接池的配置
  8. 稀疏矩阵与 spdiags函数图解
  9. Java开发笔记(一百四十六)JDBC的应用原理
  10. 单招软件职业技能测试,高职单招职业技能测试,这些知识你都了解吗?
  11. HTML5前端教程分享:JavaScript学习指南
  12. springboot+vue前后端分离实现企业人事管理系统
  13. 软件烧录的测试方法,烧录测试座使用及保养
  14. Facebook 上传小游戏流程
  15. APS Interview - Principles of Computer Organization
  16. Elasticsearch:Apache spark 大数据集成
  17. 怎么用白光干涉仪的拼接测量功能
  18. RNN LSTM 网络结构及应用
  19. vue 3.0尤雨溪亲推ui组件库naive
  20. python少儿编程课程体系_Python

热门文章

  1. alex机器人 ser_访谈 | 壹佰米机器人CO-FOUNDER & SVP:ALEX
  2. The Clouds
  3. CSS Text Style || CSS文本样式
  4. 微信公众号,点击事件
  5. ps技术的革命创新-photoshop beta版
  6. 在外网通过ssh连接访问内网教程
  7. 开始,就是未来--------迎风飞扬,遇见未知的自己
  8. mot文件解析成bin
  9. Excel函数VLOOKUP常用方法
  10. 博弈论 之 1 什么是博弈论