内部类像寄生虫一样生存在其他类【外部类】的内部。定义在类的内部的类叫内部类,它缩小了可见性。根据内部类定义结构的不同,可以把内部类分为

成员内部类和局部内部类。成员内部类定义的地方和外部类的成员变量和成员方法类似,就好像类的一个成员一样。局部类内部类则定义在方法体内,仅属于局部范围所有。

  成员内部类又可以分为:实例内部类和静态内部类。局部内部类有可以分为:普通局部内部类和匿名内部类。


一:实例内部类

  1.定义

  和实例成员变量定义位置一样。可以用四种修饰符修饰。可以再实例内部类里面定义成员变量和成员方法【静态成员变量和静态成员方法除外】。

实例内部类它属于一个具体的对象,只有外部类的实例创建出来了它才会被加载到JVM虚拟机。

//外部类
public class outer {
private String path;
//实例内部类
class Inner {
    
} }

  2.创建对象

  实例内部类的对象的创建比较特殊,必须先创建一个外部类的实例,通过外部类的实例创建。

  

Outer out = new Outer();
Inner in = out.new Inner();

  如果在外部类内部创建实例内部类对象可以直接new。

  3.访问

  (1):外部内访问实例内部类的变量和方法

    通过内部类的对象访问。

  (2):实例内部类访问外部类

    直接可以访问外部类的所有成员方法和成员变量。

   特殊情况:如果内部类有实例成员变量和实例成员方法和外部类同名怎么办?用代码说明:

先定义外部类和内部类。

package com.briup.bean;

public class InstanceOuter {

	private String path = "outer";

	public void outer() {
System.out.println("outer function");
} public class Inner {
private String path = "inner"; public String getPath() {
return path;
} public void nameLike() {
System.out.println(InstanceOuter.this.path);
System.out.println(this.path);
} public void inner() {
InstanceOuter.this.outer();
System.out.println("inner function");
} } public String getPath() {
return path;
} }

测试代码:

package com.briup.jtest;

import com.briup.bean.InstanceOuter;
import com.briup.bean.InstanceOuter.Inner; public class Test1 {
public static void main(String[] args) {
InstanceOuter outer = new InstanceOuter();
Inner inner = outer.new Inner();
inner.nameLike();
inner.inner();
}
}

控制台输出结果:

如果实例内部类要调用同名的外部类变量和方法,需要加"类名.this.变量或方法"。

二:静态内部类

  1.定义

    静态内部类使用static修饰。静态内部类随外部类加载而被jvm虚拟机加载。它的完整类名是:"包名.外部类类名.静态内部类类名",编译后的文件为"外部类类名$静态内部类类名.class",由于静态内部类是静态的,它无法访问外部类的非静态成员变量和方法。静态内部类相对于外部类来说,几乎是独立的。可以在没有外部类对象的情况下创建一个内部类对象。

//外部类
public class Outter {
//静态内部类
static class inner {
}
}

  2.创建

  通用公式:"内部类名称 对象名 = new 外部类类名.内部类类名()" ;

  外部类内部可以直接new 出来。

  

  3.访问

    (1):外部类访问静态内部类

      通过静态内部类对象访问,私有的也可以直接访问。

    (2):静态内部类访问内部类

      直接可访问外部类的静态成员方法和变量。

三:普通的局部内部类

  1.定义

    普通局部内部类没有范围概念,仅在定义的方法里有效。

public void init(String path) { //方法
  class Inner {} //普通的局部内部类
}

    本质上说,局部内部类也是独立的类,不过它的使用受到了限制。列如:不能使用static修饰,只能用final 和 abstract关键字。仅可以访问方法中final关键字的局部变量【jdk1.8新特性:可以访问不带final的局部变量,当它是final的】。

  2.创建

    它的可见范围是方法体内,在方法体内可以像普通类一样创建。

  3.访问

    仅可以访问方法中final关键字的局部变量【jdk1.8新特性:可以访问不带final的局部变量,当它是final的】。可以访问任意的外部类的成员变量。

四:匿名内部类

  1.定义

    如果一个局部类没有名称,它就是匿名内部类。

public void init(
new OneInterface {} //直接new 一个接口。 )

   匿名内部类编译后的class文件命名按照匿名内部类的排列顺序来进行的,直接在外部类后加上 '$' 和 序号。如:Outer$1.class。

  2.使用

    匿名内部类可以做什么呐?可以避免修改接口而实现同一个类中两种同名方法的调用。举一个列子说明:

  比如中国人见面问候是  "xxx,你吃饭了吗" ,美国人是 "hello,xxx"。

  接口:

package com.briup.bean;

public interface OneInterface {

    public abstract String say();
}

    bean类:

package com.briup.bean;

public class People {

    private String name;
//国家
private String nation; public People(String name, String nation) {
super();
this.name = name;
this.nation = nation;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getNation() {
return nation;
} public void setNation(String nation) {
this.nation = nation;
} public void say(OneInterface one) {
System.out.println(one.say());
}
}

测试类:

package com.briup.jtest;

import com.briup.bean.OneInterface;
import com.briup.bean.People; public class Test3 { public static void main(String[] args) {
//中国人
People china = new People("小明", "中国");
People america = new People("jack", "America"); china.say(new OneInterface() { @Override
public String say() {
return "你好,吃饭了吗? " + america.getName();
}
}); america.say(new OneInterface() { @Override
public String say() {
return "hello " + china.getName() ;
}
});
} }

总结:

  1.实例内部类可以和实例成员变量和实例成员方法类比,实例成员方法可以直接访问所有成员,实例内部类也可以。

   2.静态内部类访问可以总结成一句话:不能在静态上下文中访问非静态的成员方法和变量。静态内部类相对于外部类来说,仅仅是包含关系,缩小了命名空间,完整的类名多了一个外部类的类名。本质上是两个独立的类,JVM也不知道它们的包含关系。某种程度来说:公开的静态内部类就相当于一个普通的类。

  3.内部类的作用:

    (1):内部类可以很好的实现隐藏

       一般的非内部类,是不允许有 private 与protected权限的,但内部类可以

    (2):内部类拥有外围类的所有元素的访问权限

    (3):可是实现多重继承

    (4)可以避免修改接口而实现同一个类中两种同名方法的调用。

java基础(二):java内部类的更多相关文章

  1. java基础(二)-----java的三大特性之继承

    在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句 ...

  2. java基础二 java的跨平台特性

    一:java跨平台的特性: 1.生成不平台无关系的字节码. 2.通过和平台有关的jvm即java虚拟机来执行字节码.jvm不跨平台. 图示: 疑问:1.为什么我们不直接写字节码? 因为字节码只有jvm ...

  3. 重学JAVA基础(二):Java反射

        看一下百度的解释:       JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息     ...

  4. 学习android学习必备的java基础知识--四大内部类

    学习android必备的java基础知识--四大内部类 今天学习android课程,因为我的主专业是JAVA,但是兴趣班却有这其他专业的同学,学习android 需要具备一些java的基础知识,因此就 ...

  5. Java面试题总结之Java基础(二)

    Java面试题总结之Java基础(二) 1.写clone()方法时,通常都有一行代码,是什么? 答:super.clone(),他负责产生正确大小的空间,并逐位复制. 2.GC 是什么? 为什么要有G ...

  6. Java基础教程:内部类

    Java基础教程:内部类 内部类 内部类,是指在一个类的内部定义的类.就像下面这样: public class EnclosingClass {   . . .   public class Nest ...

  7. Java入土--Java基础(二)

    Java基础(二) 接上一讲,我们接着来聊聊Java的一些基础知识,下一讲就会进行流程的控制. 类型转换 首先呢,是类型的转换,接上一个内容的数据类型,类型转换就是数据类型更进一步的应用. 由于Jav ...

  8. 黑马程序员:Java基础总结----java注解

    黑马程序员:Java基础总结 java注解   ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! java注解 lang包中的基本注解 @SuppressWarnings ...

  9. Java基础:Java的四种引用

    在Java基础:java虚拟机(JVM)中,我们提到了Java的四种引用.包括:强引用,软引用,弱引用,虚引用.这篇博客将详细的讲解一下这四种引用. 1. 强引用 2. 软引用 3. 弱引用 4. 虚 ...

随机推荐

  1. ubuntu1604使用之旅——Qt交叉编译移植

    1.手头已有Qt-Embedded-5.7.0.tar.gz 2.解压 3.sudo cp Qt-Embedded-5.7.0 -r  /usr/local/ 4.sudo vim ~/.bashrc ...

  2. shell练习题5

    需求如下: 用shell实现,把一个文件文档中只有一个数字的行给打印出来.(以/password文件为例,自行修改) 参考解答如下 方法1 #!/bin/bash file_name=passwd n ...

  3. MySQL数据库语句

    一 . 常用mysql命令行命令        1 .启动MYSQL服务   net start mysql 停止MYSQL服务   net stop mysql 2 . netstat –na | ...

  4. c++错误

    run-time check failure #2-stack around the variable 'c' was corrupted错误产生的原因大多是因为程序定义了数组,存在数组越界.解决办法 ...

  5. IP通信基础课堂笔记----第二章(重点)

    TCP报文及传输 TCP报文主要学习的内容包括,报文格式.连接管理.流量控制.差错控制. TCP报文是由报文头部和数据两个部分组成.占20字节的报文头部包括源端口.位目的端口.序号..确认号.首部长度 ...

  6. Python03(Linux和Python简介)

    Trainning-day02回顾1.rmdir : 删除空文件夹2.rm :删除文件或者文件夹 -r 删除目录以及其内容 -i 删除前的提示 -f 强制删除3.通配符 * 匹配任意多个任意字符 ?匹 ...

  7. ArrayList、LinkedList和vector的区别

    1.ArrayList和Vector都是数组存储,插入数据涉及到数组元素移动等操作,所以比较慢,因为有下标,所以查找起来非常的快. LinkedList是双向链表存储,插入时只需要记录本项的前后项,查 ...

  8. Springboot 定时任务,service层无法注入问题详细解决

    开发一个微信小程序后台,建立websocket 长连接,需要后台开启定时任务, 定时任务定时查库,相应前台 但是具体执行过程中一直在报空指针错误,最后定位到service 为空,无法调用其相关的方法导 ...

  9. 2018-计算机系机试(第二批)-E-绝对值排序

    单点时限: 2.0 sec 内存限制: 256 MB 输入 n 个整数,按照绝对值从大到小排序.绝对值相等的整数按照整数值从小到大排序. 例如:3 个整数 -2,2 和 -6 的排序结果为 -6, - ...

  10. Flutter 开发小技巧

    1.命令行运行flutter run之后iOS报错:Could not install build/ios/iphones/Runner.app on XXXXX. try lunching Xcod ...