内部类

内部类:

一个类的内部又完整的嵌套了另一个类结构。被嵌套的类成为内部类(inner class),嵌套其他类的类称为外部类(outer class)。是类的第五大成员(1、属性 2、方法 3、构造器 4、代码块 5、内部类)

内部类最大的特点就是可以直接访问私有属性,并且可以体现类与类之间的包含关系。

基本语法:
    class Outer{    //外部类
        class Inner{    //内部类
        }
    }
    class Other{    //外部其他类
    }
入门案例:
    public class InnerClass{    //外部其他类
        public static void main(String[] args) {

        }
    }
    class Outer{
        private int n1 = 100;   //属性
        public Outer(int n1){   //构造器
            this.n1 = n1;
        }
        public void m1(){   //方法
            System.out.print("m1()");
        }
        {   //代码块
            System.out.print("代码块~~");
        }
        class Inner {   //内部类,在Outer类的内部

        }
    }

内部类的分类:

定义在外部类局部位置上(比如方法内):
  1. 局部内部类(有类名)
  2. 匿名内部类(没有类名,重点)
定义在外部的成员位置上:
  1. 成员内部类(没用static修饰)
  2. 静态内部类(使用static修饰)
局部内部类的使用:

说明:局部内部类是定义在外部类的局部位置,比如方法中,并且有类名。

  1. 可以直接访问外部类的所有成员,包括私有的

  2. 不能添加访问修饰符,因为它的地位就是一个局部变量,局部变量是不能使用修饰符的。但是可以使用final修饰,因为局部变量也可以使用final

  3. 作用域:仅仅在定义它的方法或代码块中

  4. 局部内部类–访问—>外部类的成员 [访问方式:直接访问]

  5. 外部类–访问—>局部内部类的成员

    访问方式:创建对象,再访问(注意:必须在作用域内)

  6. 外部其他类–不能访问—>局部内部类(因为 局部内部类地位是一个局部变量)

  7. 如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员) 去访问

    如:System.out.print("外部类的n2=" + 外部类名.this.n2);

演示局部内部类的使用
        public static void main(String[] args) {
            Outer02 outer02 = new Outer02;
            outer02.m1();
        }
        /*
            输出结果:
                n1=100
                Outer02 m2()
        */
        ----------------------------------------------------------
        class Outer02{  //外部类
            private int n1 =100;
            private void m2(){  //私有方法
                System.out.print("Outer02 m2()");
            }   
            public void m1(){   //方法
                //1、局部内部类是定义在外部类的局部位置,通常在方法
                //3、不能添加访问修饰符,但是可以使用final修饰
                class Inner02{  //4、局部内部类(本质仍然是一个类)
                    /*
                        如果定义一个与外部类同名的属性
                        private int n1 = 800;
                        此时,将输出
                            n1=100
                            Outer02 m2()
                        f1()方法可以写成
                    public void f1(){   //局部内部类可以直接访问外部类成员
                        System.out.print("n1=" + n1 + "外部类的n1" + Outer02.this.n1);
                        m2();
                    }
                    */
                    //2、可以直接访问外部类的所有成员,包括私有的
                    public void f1(){   //局部内部类可以直接访问外部类成员
                        System.out.print("n1=" + n1);
                        m2();
                    }
                }
                class Inner03 extends Inner02{  //如果final class Inner02 就不能继承了
                }
                //6、外部类在方法中,可以创建Inner02对象,然后调用方法即可
                Inner02 inner02 = new Inner02();
                inner02.f1();
            }
        }

匿名内部类
说明:

匿名内部类是定义在外部类的局部位置,比如方法中,并且没有类名

1、本质是一个类,2、是一个内部类,3、该类没有名字,4、同时还是一个对象

  • 匿名内部类的基本语法
            new 类或接口(参数列表){
                类体
            };
举例说明:
            /*
                演示匿名内部类的使用
            */
            public Class AnonymousInnerClass{
                public static void main(String[] args) {
                    Outer04 outer04 = new Outer04();
                    outer02.method();
                }
            }
            class Outer04{  //外部类
                private int n1 = 10;
                public void method(){
                    //基于接口的匿名内部类
                    //1、需求:想使用接口IA
                    /*
                        传统方法:写一个类,实现该接口,并创建对象
                        但,如果这个对象只用一次,以后再也不用的话 创建这么多对象会很浪费
                        此时,可以使用匿名内部类来简化开发
                    */
                    --------------------------------------
                    Tiger tiger = new Toger();
                    tiger.cry();
                    --------------------------------------
                    匿名内部类:
                    /*
                        编译类型:IA
                        运行类型:匿名内部类

                        底层: 会自动分配类名,Outer041,这个类用一次就没有了
                            class Outer041 implements IA{
                                @Override
                                public void cry(){
                                    System.out.print("老虎叫唤~~");
                                }
                            }
                    */
                    /*
                        jdk底层在创建匿名内部类 Outher041,立马就创建了 Outher041实例,
                        并且把地址返回给tiger
                        匿名内部类使用一次就不能再使用,但对象可以反使用
                        匿名内部类创建了一个方法后自动销毁,但他的小孩子对象继承了它的方法本领
                    */
                    IA tiger = new IA(){
                        @Override
                        public void cry(){
                            System.out.print("老虎叫唤~~~~");
                        }
                    };
                    tiger.cry();
                    --------------------------------------              
                }
            }
            interface IA{
                public void cry();
            }
            //实现接口
            class Tiger implements IA{
                @Override
                public void cry(){
                    System.out.print("老虎叫唤~~");
                }
            }
            class Father{
                public Father(String name){
                }
                public void test(){
                }
            }
            abstract class Animal{  //抽象类
                abstract void eat();
            }
            //演示基于类的匿名内部类
            Father father = new Father("jack"){
                @Override
                public void test(){
                    System.out.print("匿名内部类重写了test方法");
                }
            };
            /*
                class Outer042 extends Father{}    //这样做了之后就是一个新的Outer042类,
                                                      不再是Father类了
                分析:
                    father编译类型:Father
                          运行类型:Outer04$2
                如果不带大括号,那么  编译类型和运行类型都是Father
            */
            //基于抽象类的匿名内部类
            new Animal(){
                @Override
                void eat(){
                    System.out.print("小狗吃骨头");
                }
            }
  • 匿名内部类既是一个类的定义,同时它本身也是一个对象,因此从语法上看,它既有定义类的特征,也有创建对象的特征,对前面代码分析可以看出来这个特点,因此可以看出这个特点,因此可以调用匿名内部类方法
            public class AnonymousInnerClassDetail{
                public static void main(String[] args) {
                }
            }
            class Outer05{
                private int n1 = 99;
                public void f1(){
                    //创建一个基于类的匿名内部类
                    Person p = new Person(){
                        new Person(){
                            @Override
                            public void hi(){
                                System.out.print("匿名内部类重写了hi方法");
                            }
                        }
                    }
                    p.hi();//动态绑定
                    /*
                        编译类型:Person
                        运行类型:Outer05$1
                    */
                    //也可以直接调用
                    new Person(){
                        @Override
                        public void hi(){
                            System.out.print("匿名内部类重写了hi方法,哈哈~!");
                        }
                    }.hi(); //匿名内部类本身也是返回对象,所以直接.hi()也是允许的
                }
            }
            class Person{   //类
                public void hi(){
                    System.out.print("Person hi()");
                }
            }
  • 可以直接访问外部类的所有成员,包含私有的
  • 不能添加访问修饰符,因为它的地位就是一个局部变量
  • 作用域:仅仅在定义它的方法或代码块中
  • 匿名内部类–访问—>外部类成员 访问方法:直接访问
  • 外部其他类–不能访问—>匿名内部类(因为 局部内部类地位是一个局部变量)
  • 如果外部类和匿名内部类的成员重名时,默认遵循就近原则,
  • 如果想访问外部类的成员,则可以使用(外部类名.this.成员) 去访问
匿名内部类实践:

当作实参直接传递,简洁高效

            public class InnerClassExercise01{
                public static void main(String[] args) {
                    //当作实参直接传递,简洁高效
                    f1(new IL(){
                        @Override
                        public void show(){
                            System.out.print("这是一幅名画~~~");
                        }
                    }); 
                }
            }

传统写法:

            //1、类->实现IL
            class Picture implements IL {
                @Override
                public void show(){
                    System.out.print("这是一幅名画~~~");
                }
            }
            //2、
            f1(new Picture());  //相当于把实现了接口的Picture的对象传给了f1()
            ------------------------------------------------------
                //静态方法,形参是接口类型
                public static void f1(IL il){
                    il.show();
                }
            //接口
            interface IL{
                void show();
            }
创作不易!转载请注明作者及文章链接或作者博客链接——
- 作者:pidanxia
- 链接:https://pidanxia.ink
(链接可为:**文章链接**或者**作者博客链接**)
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇