Java基本概念:内部类


一、简介

描述:

  • 很多时候我们创建类的对象的时候并不需要使用很多次,每次只使用一次,这个时候我们就可以使用内部类了。
  • 内部类不是在一个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接口的方法
    }
}

(0)

相关推荐

  • 方法重写

    方法重写 重写都是方法的重写,与属性无关 父类的引用可以指向子类,就是new一个子类的对象数据类型可以写为父类,new子类是可以指向父类的 重写的快捷键:Alt+insert 对静态方法调用的时候,调 ...

  • Java之static作用的全方位总结

    Java之static作用的全方位总结

  • Java基本概念:接口

    一.简介 描述: 普通类只有具体实现,抽象类具体实现和规范都有,接口只有规范! 接口就是比抽象类还抽象的抽象类,可以更加规范的对子类进行约束,全面专业地实现了规范和具体实现的分离. 抽象类还提供某些具 ...

  • Java基本概念:多态

    一.简介 描述: 多态性是面向对象编程中的一个重要特性,主要是用来实现动态联编的.换句话说,就是程序的最终状态只有在执行过程中才被决定,而非在编译期间就决定了.这对于大型系统来说能提高系统的灵活性和扩 ...

  • 解析Java编程思想--内部类

    一个类的定义可以放在另一个类的定义内,它叫做内部类.内部类是一种非常有用的特性,因为它可以让你将逻辑相关的类组织在一起,并且控制类的视觉效果.但我们必须认识到,内部类和组合是截然不同的概念.在最初,内 ...

  • Java异常处理(异常基本概念)

    一:异常的基本概念 当我们的程序在运行中出现了不合理的地方则会出现异常,异 常就是终止程序运行的指令,当一行代码出现异常之后,那么后面的代码就不再继续执行,如果要让后面的代码继续需要将异常处理,异常处 ...

  • Java分布式锁的概念以及使用优点

    普通的锁,即在单机多线程环境下,当多个线程需要访问同一个变量或代码片段时,被访问的变量或代码片段叫做临界区域,我们需要控制线程一个一个的顺序执行,否则会出现并发问题. 设置一个各个线程都能看的见的标志 ...

  • Java封装的概念详解

    一:封装的概念 Java是一门面向对象的语言,面向对象就是一种以组件化模式进行代码开发的思想,面向对象的理解你需要学完整个课程才会有感觉,面向对象有 三个基本特征:封装.继承.多态. 今天学习的是封装 ...

  • Java局部内部类

    局部内部类是指在一个方法中定义的内部类.示例代码如下: public class Test { public void method() { class Inner { // 局部内部类 } } }1 ...

  • Java开发之多线程的基本概念与如何避坑

    Java开发之多线程的基本概念与如何避坑

  • Java Web基本概念

    目录 JSP 架构 Tomcat 常见状态码 虚拟路径 虚拟主机 jsp访问流程 JSP JSP:动态网页 静态和动态: 不能和是否有"动感"混为一谈 是否随着时间,地点,用户操作 ...