这是我学习Java内部类的笔记

1.为什么使用内部类?
使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,
对于内部类都没有影响
1.1.使用内部类最大的优点就在于它能够非常好的解决多重继承的问题,使用内部类还能够为我们带来如下特性:
(1)、内部类可以用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独。
(2)、在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类。
(3)、创建内部类对象的时刻并不依赖于外围类对象的创建。
(4)、内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体。
(5)、内部类提供了更好的封装,除了该外围类,其他类都不能访问。
2.内部类分类:
(一).成员内部类:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Outer{
        private int age = 99;
        String name = "Coco";
        public class Inner{
            String name = "Jayden";
            public void show(){
                System.out.println(Outer.this.name);
                System.out.println(name);
                System.out.println(age);
            }
        }
        public Inner getInnerClass(){
            return new Inner();
        }
        public static void main(String[] args){
            Outer o = new Outer();
            Inner in = o.new Inner();
            in.show();
        }
    }

1.Inner 类定义在 Outer 类的内部,相当于 Outer 类的一个成员变量的位置,Inner 类可以使用任意访问控制符,
如 public 、 protected 、 private 等
2.Inner 类中定义的 show() 方法可以直接访问 Outer 类中的数据,而不受访问控制符的影响,
如直接访问 Outer 类中的私有属性age
3.定义了成员内部类后,必须使用外部类对象来创建内部类对象,而不能直接去 new 一个内部类对象,
即:内部类 对象名 = 外部类对象.new 内部类( );
4.编译上面的程序后,会发现产生了两个 .class 文件: Outer.class,Outer$Inner.class{}
5.成员内部类中不能存在任何 static 的变量和方法,可以定义常量:
(1).因为非静态内部类是要依赖于外部类的实例,而静态变量和方法是不依赖于对象的,仅与类相关,
简而言之:在加载静态域时,根本没有外部类,所在在非静态内部类中不能定义静态域或方法,编译不通过;
非静态内部类的作用域是实例级别
(2).常量是在编译器就确定的,放到所谓的常量池了
★★友情提示:
1.外部类是不能直接使用内部类的成员和方法的,可先创建内部类的对象,然后通过内部类的对象来访问其成员变量和方法;
2.如果外部类和内部类具有相同的成员变量或方法,内部类默认访问自己的成员变量或方法,如果要访问外部类的成员变量,
可以使用 this 关键字,如:Outer.this.name
(二).静态内部类: 是 static 修饰的内部类,
1.静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问
2.如果外部类的静态成员与内部类的成员名称相同,可通过“类名.静态成员”访问外部类的静态成员;
如果外部类的静态成员与内部类的成员名称不相同,则可通过“成员名”直接调用外部类的静态成员
3.创建静态内部类的对象时,不需要外部类的对象,可以直接创建 内部类 对象名 = new 内部类();

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Outer{
            private int age = 99;
            static String name = "Coco";
            public static class Inner{
                String name = "Jayden";
                public void show(){
                    System.out.println(Outer.name);
                    System.out.println(name);                  
                }
            }
            public static void main(String[] args){
                Inner i = new Inner();
                i.show();
            }
        }

(三).方法内部类:其作用域仅限于方法内,方法外部无法访问该内部类
(1).局部内部类就像是方法里面的一个局部变量一样,是不能有 public、protected、private 以及 static 修饰符的
(2).只能访问方法中定义的 final 类型的局部变量,因为:
当方法被调用运行完毕之后,局部变量就已消亡了。但内部类对象可能还存在,
直到没有被引用时才会消亡。此时就会出现一种情况,就是内部类要访问一个不存在的局部变量;
==>使用final修饰符不仅会保持对象的引用不会改变,而且编译器还会持续维护这个对象在回调方法中的生命周期.
局部内部类并不是直接调用方法传进来的参数,而是内部类将传进来的参数通过自己的构造器备份到了自己的内部,
自己内部的方法调用的实际是自己的属性而不是外部类方法的参数;
防止被篡改数据,而导致内部类得到的值不一致

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
   /*
        使用的形参为何要为 final???
         在内部类中的属性和外部方法的参数两者从外表上看是同一个东西,但实际上却不是,所以他们两者是可以任意变化的,
         也就是说在内部类中我对属性的改变并不会影响到外部的形参,而然这从程序员的角度来看这是不可行的,
         毕竟站在程序的角度来看这两个根本就是同一个,如果内部类该变了,而外部方法的形参却没有改变这是难以理解
         和不可接受的,所以为了保持参数的一致性,就规定使用 final 来避免形参的不改变
         */
        public class Outer{
            public void Show(){
                final int a = 25;
                int b = 13;
                class Inner{
                    int c = 2;
                    public void print(){
                        System.out.println("访问外部类:" + a);
                        System.out.println("访问内部类:" + c);
                    }
                }
                Inner i = new Inner();
                i.print();
            }
            public static void main(String[] args){
                Outer o = new Outer();
                o.show();
            }
        }    
(3).注意:在JDK8版本之中,方法内部类中调用方法中的局部变量,可以不需要修饰为 final,匿名内部类也是一样的,主要是JDK8之后增加了 Effectively final 功能
反编译jdk8编译之后的class文件,发现内部类引用外部的局部变量都是 final 修饰的

(四).匿名内部类:
(1).匿名内部类是直接使用 new 来生成一个对象的引用;

(2).对于匿名内部类的使用它是存在一个缺陷的,就是它仅能被使用一次,创建匿名内部类时它会立即创建一个该类的实例,
该类的定义会立即消失,所以匿名内部类是不能够被重复使用;
(3).使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口;
(4).匿名内部类中是不能定义构造函数的,匿名内部类中不能存在任何的静态成员变量和静态方法;
(5).匿名内部类中不能存在任何的静态成员变量和静态方法,匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法
(6).匿名内部类初始化:使用构造代码块!利用构造代码块能够达到为匿名内部类创建一个构造器的效果

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  public class OuterClass {
            public InnerClass getInnerClass(final int   num,String str2){
                return new InnerClass(){
                    int number = num + 3;
                    public int getNumber(){
                        return number;
                    }
                };        /* 注意:分号不能省 */
            }
            public static void main(String[] args) {
                OuterClass out = new OuterClass();
                InnerClass inner = out.getInnerClass(2, "chenssy");
                System.out.println(inner.getNumber());
            }
        }
        interface InnerClass {
            int getNumber();
        }         

java面试题之----Java内部类的更多相关文章

  1. [Java面经]干货整理, Java面试题(覆盖Java基础,Java高级,JavaEE,数据库,设计模式等)

    如若转载请注明出处: http://www.cnblogs.com/wang-meng/p/5898837.html   谢谢.上一篇发了一个找工作的面经, 找工作不宜, 希望这一篇的内容能够帮助到大 ...

  2. 一线互联网企业常见的14个Java面试题,Java面试题集大全等你拿,颤抖吧程序员!

    本文由尚学堂学员们根据自己参加过的面试回忆.总结而成,一线互联网企业常见的14个Java面试题,包括各大互联网企业.创业小公司,互联网企业.传统软件公司.对于刚毕业和想要跳槽的宝宝们,再适用不过啦,赶 ...

  3. Java面试题:Java中怎么样实现多线程

    方法一:继承 Thread 类,覆盖方法 run(),我们在创建的 Thread 类的子类中重写 run() ,加入线程所要执行的代码即可. 下面是一个例子: public class MyThrea ...

  4. 转载:[Java面经]干货整理, Java面试题(覆盖Java基础,Java高级,JavaEE,数据库,设计模式等)

    原文:http://www.cnblogs.com/wang-meng/p/5898837.html 一:继承.抽象类与接口区别.访问控制(private, public, protected,默认) ...

  5. Java面试题系列 ----- Java基础面试题(91道)

    更多详情点击查看,点这里!这里!!这里!!! 文末获取所有面试PDF文档! Java概述 1. 何为编程 编程就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码,并最终得到结果的过程. 为了 ...

  6. 【Java面试题】12 内部类可以引用它的包含类的成员吗?有没有什么限制?

    完全可以.如果不是静态内部类,那没有什么限制! 如果你把静态嵌套类当作内部类的一种特例,那在这种情况下不可以访问外部类的普通成员变量,而只能访问外部类中的静态成员,例如,下面的代码: class Ou ...

  7. JAVA面试题 浅析Java中的static关键字

    面试官Q1:请说说static关键字,你在项目中是怎么使用的? static 关键字可以用来修饰:属性.方法.内部类.代码块: static 修饰的资源属于类级别,是全体对象实例共享的资源: 使用 s ...

  8. JAVA面试题0 JAVA语言的基本知识

    JAVA语言的特点是什么? >面向对象:两个基本概念:类和对象:三大基本特性:封装.继承.多态: >健壮性:java吸收了C/C++的优点,但是去掉了它们影响健壮性的部分,例如指针和内存申 ...

  9. Java面试题之Java基础

    1. JDK 和 JRE 有什么区别? JRE(JavaRuntimeEnvironment,Java运行环境),也就是Java平台.所有的Java 程序都要在JRE下才能运行.普通用户只需要运行已开 ...

随机推荐

  1. 【linux】如何查看文件的创建、修改时间

    本篇博文旨在介绍Linux下查看文件时间的方法:并介绍如何使用touch指令来进行文件时间的创建以及修改 如何查看文件的时间信息利用stat指令查看文件信息 三种时间的介绍ATime ——文件的最近访 ...

  2. 一个迷你的 Node.js 基于 Express 的 MVR 模式的 API工程 的分析

    1. 工程说明 该工程是基于 Express 库,编写的一个 API 查询返回的一个微型应用. API Resource 就是把 API 的内容当做网络资源去处理.工程中的路由访问也是返回 API 内 ...

  3. vue 路由传参 、接收参数

    传参组件 一. <router-link :to='"/main/course?navName=" +item.columnName + "&id=&quo ...

  4. 时钟时间,系统cpu时间,用户cpu时间

    进程的3种状态:阻塞,就绪,运行   度量一个进程的执行时间,unix为进程维护了3个时间,即时钟时间,用户CPU时间,系统CPU时间.   时钟时间又被称为墙上时钟时间,wall clock tim ...

  5. IO概念解析------同步异步阻塞非阻塞

    各个IO Model的比较如图所示: 阻塞和非阻塞强调的是程序在等待调用结果(消息,返回值)时的状态.  阻塞调用是指调用结果返回之前,当前线程会被挂起.调用线程只有在得到结果之后才会返回.非阻塞调用 ...

  6. (转)Linux运维MySQL必会面试题100道

    老男孩教育Linux运维班MySQL必会面试题100道 (1)基础笔试命令考察 (要求:每两个同学一组,一个口头考,一个上机实战作答,每5个题为一组,完成后换位) 1.开启MySQL服务 2.检测端口 ...

  7. Bugfree安装与使用

    第一步:下载XAMPP和bugfree http://www.bugfree.org.cn/ http://www.apachefriends.org/zh_cn/xampp.html 第二步:安装 ...

  8. javah找不到类文件

    这样即可,在src目录下寻找类,类要写全,即包名.类名

  9. 资料汇总--Java

    01.从零开始学springBoot 02.java资源大全中文版 03.谷歌 中国

  10. [转]nopCommerce 3.9 版本发行

    本文转自:http://www.cnblogs.com/xoray007/p/nopCommerce-39-release.html NopCommerce中文信息地址:http://www.nopc ...