java基础名词解析(三)全网最全内部类详解,楼主吐血总结

举报
小鲍侃java 发表于 2021/09/10 00:47:53 2021/09/10
【摘要】 成员内部类 class OutClass { class InnerClass { public String SayHi() { return "你好"; } } }...

成员内部类

class OutClass {
	class InnerClass {
		public String SayHi() {
           return "你好";
		}
	}
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

特点:
1.内部类能够无条件的访问外部类的成员变量,外部类要访问内部类成员变量需要使用new。
2.内部类和外部类有相同名称的变量或者是方法,访问外部类方式为:外部类.this.方法。
3.内部类是依赖外部类的,只有先有外部类才能有内部类。调用内部类方法为:

OutClass out = new OutClass();
OutClass.InnerClass inner = out.new InnerClass();

  
 
  • 1
  • 2

4.内部类的权限可以public,protected,保护类型和private。而外部类只能是public和保护类型。
5.成员内部类不能存在static关键字,非静态内部类也可以定义静态成员但需要同时有final关键词修饰。

局部内部类

是指内部类定义在一个类的方法,代码块中。
1.局部内部类只能在代码代码块、方法体内和作用域中使用(如创建对象和使用类对象等)
2.局部内部类访问作用域内的局部变量,该局部变量需要使用final修饰。
3.可以使用abstract修饰,声明为抽象类。
4.只能在定义该类的方法中实例化。

public class Outer {
    private int s = 100;
    private int out_i = 1;

    public void f(final int k) {
        final int s = 200;
        int i = 1;
        final int j = 10;

        // 定义在方法内部
        class Inner {
            int s = 300;// 可以定义与外部类同名的变量

            // static int m = 20;//不可以定义静态变量
            Inner(int k) {
                inner_f(k);
            }
            int inner_i = 100;
            void inner_f(int k) {
                // 如果内部类没有与外部类同名的变量,在内部类中可以直接访问外部类的实例变量
                System.out.println(out_i);
                // 可以访问外部类的局部变量(即方法内的变量),但是变量必须是final的
                System.out.println(j);
                // System.out.println(i);
                // 如果内部类中有与外部类同名的变量,直接用变量名访问的是内部类的变量
                System.out.println(s);
                // 用this.变量名访问的也是内部类变量
                System.out.println(this.s);
                // 用外部类名.this.内部类变量名访问的是外部类变量
                System.out.println(Outer.this.s);
            }
        }
        new Inner(k);
    }

    public static void main(String[] args) {
        // 访问局部内部类必须先有外部类对象
        Outer out = new Outer();
        out.f(3);
    }
}

  
 
  • 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
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

静态内部类

使用static修饰的内部类。
1.不依赖外部类,不能使用外部类非静态的变量和方法。
2.不需要如成员内部类一样,生成外部类对象来生成内部类。
3.静态内部类中可以定义静态或者非静态的成员。
4.外部类访问内部类的静态成员:内部类.静态成员。
5.外部类访问内部类的非静态成员:实例化内部类即可。
6.可以有非静态的方法或者变量。
使用场景:
1.当外部需要使用内部类而内部类不依赖与外部类的资源。
2.能够单独生成对象。
3.节省资源。

public class Outer {
    private static int i = 1;
    private int j = 10;
    public static void outer_f1() {}
    public void outer_f2() {}

    // 静态内部类可以用public,protected,private修饰
    // 静态内部类中可以定义静态或者非静态的成员
    private static class Inner {
        static int inner_i = 100;
        int inner_j = 200;

        static void inner_f1() {
            // 静态内部类只能访问外部类的静态成员(包括静态变量和静态方法)
            System.out.println("Outer.i" + i);
            outer_f1();
        }

        void inner_f2() {
            // 静态内部类不能访问外部类的非静态成员(包括非静态变量和非静态方法)
            // System.out.println("Outer.i"+j);
            // outer_f2();
        }
    }

    public void outer_f3() {
        // 外部类访问内部类的静态成员:内部类.静态成员
        System.out.println(Inner.inner_i);
        Inner.inner_f1();
        // 外部类访问内部类的非静态成员:实例化内部类即可
        Inner inner = new Inner();
        inner.inner_f2();
    }

    public static void main(String[] args) {
        new Outer().outer_f3();
    }
}

  
 
  • 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
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

匿名内部类

就是没有名字的内部类。
匿名内部类的格式:

      new 接口或父类(){
              重写抽象方法
      };

  
 
  • 1
  • 2
  • 3

个人理解就是没有实现一个接口,但是想重写接口中的方法并且调用并返回。
目的:
1.可以使命名变得简洁
2.使代码更加紧凑,简洁,封装性比内部类更优
3.一个类用于继承其他类或是实现接口,无需增加其他的方法,只是对继承方法实现 覆盖。

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();
}

----------------
Output:
5

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

如果不适用匿名内部类

interface InnerClass {
    int getNumber(int a);
}

class InnerClassImpl{ 
   int getNumber(int a){
   system.out.print(a);}
}

InnerClass  InnerClass  = new InnerClassImpl();
使用匿名内部类之后
InnerClass  InnerClass =  new InnerClass (){
    public int getNumber(int a){
                return a;
            }
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

特点:
1.匿名内部类是没有访问修饰符的。
2.new 匿名内部类,这个类首先是要存在的。如果我们将那个InnerClass接口注释掉,就会出现编译出错。
3.注意getInnerClass()方法的形参,第一个形参是用final修饰的,而第二个却没有。同时我们也发现第二个形参在匿名内部类中没有使用过,所以当所在方法的形参需要被匿名内部类使用,那么这个形参就必须为final。
4. 匿名内部类是唯一一种没有构造方法的类。
5. 匿名内部类不能定义任何静态成员、方法和类。

使用内部类的原因:

1.可以实现多重继承。(不同的内部类可以继承不同的类)。
2.内部类可以更好的隐藏。
3.当我们不想写接口的实现或只是用一次对象时可以使用匿名内部类。
4.每个内部类都是一个单独的个体。



文章来源: baocl.blog.csdn.net,作者:小黄鸡1992,版权归原作者所有,如需转载,请联系作者。

原文链接:baocl.blog.csdn.net/article/details/82814355

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。