面向对象下——内部类

内部类

一个类的内部又完整的嵌套了另一个类结构,被嵌套的类称为内部类,嵌套其他类的类称为外部类

特点

可以直接访问私有属性,并且可类与类之间的包含关系

语法

class outer{ //外部类
    class inner{ //内部类
        
    }
}
class Other{ //外部其他类
    
}

分类

定义在外部类的局部位置上(通常在方法中 ,但也可在代码块中 )

  • 局部内部类
  • 匿名内部类(重点)

定义在外部类的成员位置上

  • 成员内部类(无static修饰)
  • 静态内部类(使用static修饰)
(一)局部内部类
语法
class outer{ //外部类
    {
        class inner0{ //声明在代码块中的局部内部类
        
        }
    }
    
    权限修饰符 关键字 返回类型 方法名(参数列表){
        class inner1{ //声明在方法中的局部内部类
        
        }
    }    
}

使用细节
  1. 可以访问外部类的所有成员(包括私有)

  2. 不能添加访问修饰符。局部内部类的地位和局部变量等同,局部变量是不能添加修饰符(final除外)的,局部变量和局部内部类都可以用final修饰

  3. 作用域:只能在所定义位置的方法体内或代码块中使用

  4. 内部类可以直接访问外部类的成员

  5. 外部类可在方法中实例化内部类对象,通过对象.方法访问内部类的成员

    class test{
        public static void main(String[] args){
            Outer o = new Outer();
            o.k(); //输出 内部类...
        }
    }
    class outer{
        public void k(){
            class Inner{  //局部内部类
                public void j(){
                    System.out.println("内部类...");
                }
            }
            Inner n = new Inner();
            n.j();
        }
    }
    
  6. 外部其他类不能访问局部内部类

  7. 如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则使用(外部类名.this.成员)来访问(外部类名.this本质上是外部类的对象,具体是哪个对象则要看是谁调用了该内部类所在的方法)

(二)匿名内部类

匿名内部类仍然是定义在外部类的局部位置,比如方法或代码块中

匿名内部类没有名字(显式没有名字,但实际上系统为它分配了名字(外部类名$1))

匿名内部类同时还是一个对象

语法
new 类或接口(参数列表){
    类体
};
使用情景

某些类在开发过程中只会使用一次,这时对于只使用一次的类进行类的定义就会显得有些繁琐,因此便采用匿名内部类的方式来使用这些只会被使用一次的类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xIjD4AxM-1641113551327)(%E5%86%85%E9%83%A8%E7%B1%BB.assets/image-20220102144322561.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q37lf97F-1641113551331)(%E5%86%85%E9%83%A8%E7%B1%BB.assets/image-20220102144441118.png)]

基于接口的匿名内部类
IA inner = new IA(){
    public void eat(){
        sout("吃...");
    }
}
implement IA{
    public void eat();
}

解释:inner的编译类型是Inner,而运行类型则是匿名内部类。当执行IA(){…}实际上在系统内部自动声明了一个实现IA接口的匿名内部类,之后便创建了这个匿名内部类的实例,并将其地址赋给inner

基于类的匿名内部类

思想和基于接口的匿名内部类大致相同

Animal animal = new Animal("小黄狗"){
    public void eat(){
        sout("吃骨头...");
    }
}
class Animal{
    String name;
    public void eat();
}

解释:animal的编译类型是Animal,而允许类型是匿名内部类。当执行Animal(…){…}时系统内部将自动声明一个继承Animal类的匿名内部类,之后便创建了这个匿名内部类的实例,并将其地址赋给animal

使用细节
  1. 可以访问外部类的所有成员,包括私有
  2. 不能添加访问修饰符
  3. 作用域:方法体内或代码块中
  4. 外部其它类不能访问匿名内部类
  5. 如果外部类和匿名 内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则使用(外部类名.this.成员)来访问
具体实践

当做实参直接传递

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PFLmugrd-1641113551332)(%E5%86%85%E9%83%A8%E7%B1%BB.assets/image-20220102153556251.png)]

(三)成员内部类

定义在外部类的成员位置,并且没有static修饰

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

  2. 可以添加任何访问修饰符(public、static、缺省、private),其地位等同于类成员

  3. 作用域:整个类体

  4. 外部类访问成员内部类,需要在外部类的方法中实例化成员内部类

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

  6. 外部其它类也可访问成员内部类

    • 通过外部类的对象实例化一个成员内部类

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rNM4mzM5-1641113551334)(%E5%86%85%E9%83%A8%E7%B1%BB.assets/image-20220102160249786.png)]

    • 在外部类中编写一个方法返回成员内部类的实例

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lzgv9QiB-1641113551335)(%E5%86%85%E9%83%A8%E7%B1%BB.assets/image-20220102160435532.png)]

(四)静态内部类

定义在外部类的成员位置,被static修饰

使用细节
  1. 可以直接访问外部类的所有静态成员,包括私有,但不能直接访问非静态成员(地位等同于静态方法)

  2. 可以添加任何访问修饰符(public、static、缺省、private),其地位等同于类成员

  3. 作用域:整个类体

  4. 外部类访问静态内部类,需要在外部类中的方法中 实例化静态内部类

  5. 如果外部类和静态内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则使用(外部类名.成员)来访问

  6. 外部其它类也可访问静态内部类

    • 通过类名直接访问(静态)

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hY2b000D-1641113551336)(%E5%86%85%E9%83%A8%E7%B1%BB.assets/image-20220102162430444.png)]

    • 在外部类中编写一个方法返回静态内部类的实例

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eNFvCYGq-1641113551338)(%E5%86%85%E9%83%A8%E7%B1%BB.assets/image-20220102162854928.png)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值