zoukankan      html  css  js  c++  java
  • java 内部类

    类都对应于一个独立的Java源文件,但一个类还可以放在另一个类的内部,称之为内部类,相对而言,包含它的类称之为外部类。

    内部类与包含它的外部类有比较密切的关系,而与其他类关系不大,定义在类内部,可以实现对外部完全隐藏,可以有更好的封装性,代码实现上也往往更为简洁。

    内部类只是Java编译器的概念,对于Java虚拟机而言,它是不知道内部类这回事的,每个内部类最后都会被编译为一个独立的类,生成一个独立的字节码文件。

    在Java中,根据定义的位置和方式不同,主要有4种内部类。   

    ▪静态内部类。   

    ▪成员内部类。   

    ▪方法内部类。 

    ▪匿名内部类。

    其中,方法内部类是在一个方法内定义和使用的;匿名内部类使用范围更小,它们都不能在外部使用;成员内部类和静态内部类可以被外部使用,不过它们都可以被声明为private,这样,外部就不能使用了。

    静态内部类

    public class Outer {
    
        private static int shared = 100;
    
        public static class StaticInner {//静态内部类
    
            public void innerMethod() {
                System.out.println("inner " + shared);
            }
        }
    
        public void test() {
            StaticInner si = new StaticInner();
            si.innerMethod();
        }
    }
    
    class Test {
        public static void main(String[] args) {
            Outer.StaticInner si = new Outer.StaticInner();//通过“外部类.静态内部类”的方式使用
            si.innerMethod();
        }
    }

    静态内部类与静态变量和静态方法定义的位置一样,也带有static关键字,只是它定义的是类

    静态内部类的使用场景是很多的,如果它与外部类关系密切,且不依赖于外部类实例,则可以考虑定义为静态内部类。

    也可以看一些在Java API中使用静态内部类的例子:   

    ▪Integer类内部有一个私有静态内部类IntegerCache,用于支持整数的自动装箱。   

    ▪表示链表的LinkedList类内部有一个私有静态内部类Node,表示链表中的每个节点。   

    ▪Character类内部有一个public静态内部类UnicodeBlock,用于表示一个Unicode block。

    成员内部类

    与静态内部类相比,成员内部类没有static修饰符,少了一个static修饰符,含义有很大不同

    public class Outer {
        private int a = 100;
    
        private void action() {
            System.out.println("action");
        }
    
        public void test() {
            Inner inner = new Inner();
            inner.innerMethod();
        }
    
        public class Inner {
            public void innerMethod() {
                System.out.println("outer a " + a);//直接访问外部类私有实例变量a
                Outer.this.action();//通过“外部类.this.xxx”的方式引用外部类的实例变量和方法
            }
        }
    }
    
    class Test {
        public static void main(String[] args) {
            Outer outer = new Outer();
            Outer.Inner inner = outer.new Inner();//创建内部类对象的语法是“外部类对象.new内部类()”
            inner.innerMethod();
        }
    }

    成员内部类有哪些应用场景呢?如果内部类与外部类关系密切,需要访问外部类的实例变量或方法,则可以考虑定义为成员内部类。外部类的一些方法的返回值可能是某个接口,为了返回这个接口,外部类方法可能使用内部类实现这个接口,这个内部类可以被设为private,对外完全隐藏。

    比如,在Java API的类LinkedList中,它的两个方法listIterator和descendingIterator的返回值都是接口Iterator,调用者可以通过Iterator接口对链表遍历,listIterator和descend-ingIterator内部分别使用了成员内部类ListItr和DescendingIterator,这两个内部类都实现了接口Iterator。

    方法内部类

    内部类还可以定义在一个方法体中。

    public class Outer {
        private int a = 100;
    
        public void test(final int param) {
            final String str = "hello";
            final String[] str2 = new String[]{"hello"};
            class Inner {
                public void innerMethod() {
                    System.out.println("outer a " + a);//直接访问了外部私有实例变量a
                    System.out.println("param " + param);
                    System.out.println("local var " + str);
                    str2[0] = "hello world";
                }
            }
            Inner inner = new Inner();
            inner.innerMethod();
            System.out.println(str2[0]);
        }
    }
    
    class Test {
        public static void main(String[] args) {
            Outer outer = new Outer();
            outer.test(1);
        }
    }

    方法内部类可以用成员内部类代替,至于方法参数,也可以作为参数传递给成员内部类。不过,如果类只在某个方法内被使用,使用方法内部类,可以实现更好的封装。

    匿名内部类

    匿名内部类没有单独的类定义,它在创建对象的同时定义类,语法如下:

    new 父类(参数列表) {   

      //匿名内部类实现部分

    }

    或者

    new 父接口() {   

      //匿名内部类实现部分

    }

    匿名内部类是与new关联的,在创建对象的时候定义类,new后面是父类或者父接口,然后是圆括号(),里面可以是传递给父类构造方法的参数,最后是大括号{},里面是类的定义。

    匿名内部类跟详细的介绍: https://www.cnblogs.com/ooo0/p/12582296.html

    匿名内部类能做的,方法内部类都能做。但如果对象只会创建一次,且不需要构造方法来接受参数,则可以使用匿名内部类,这样代码书写上更为简洁。

    文章参考来源:java编程的逻辑

  • 相关阅读:
    Vue——data中的属性规范
    python的字符串用法
    python笔录第一周
    Mac下python版本的更新
    我的第一篇博客
    C语言-控制语句(循环)
    C语言-控制语句(分支与跳转)
    C语言-函数
    C语言-数组与指针
    C语言-堆和栈
  • 原文地址:https://www.cnblogs.com/ooo0/p/12712356.html
Copyright © 2011-2022 走看看