Java笔记——内部类

目录

成员内部类

内部类存在的原因

成员内部类

关于成员内部类产生对象的两种方式

私有内部类

静态内部类

小总结

方法内部类(了解即可)

匿名内部类

Lambda表达式​编辑

函数式接口

​编辑

Lambda表达式的四种情况


所谓的内部类就是将一个类嵌套到另一个类的内部的操作

核心思路:就把内部类看成当前类中一个普通属性来看待

类似于 public String ,private int ...等等

普通类包含:就是由一系列的属性和方法组成
 

内部类就是在普通类里面又创建了一个类罢了。

现实生活中举例:如果把一个人看成一个类的话

那么心脏就是人体的一个内部类

或者

发动机和汽车的关系,发动机有很多属性和方法。发动机就是汽车就是一个内部类

为啥要把这些类套在另一个类的内部呢?

内部类的设计也是一种封装的思想~~~
封装体现的就是保护性和易用性
心脏封装到人类的内部  相当于 
保护

发动机封装到汽车的内部  相当于  易用
 

注释:封装的种类有很多,不止我们之前学的private这些,内部类也属性封装的一种

成员内部类

 其中类外部类的成员方法或属性名称相同都没事,不影响。

内部类就是外部类的一部分

在下面这种情况,Outter 就是外部类, Inner就是内部类,Inner就是Outter的一部分。

 内部类里面可以直接访问外部类的所有方法和属性,不管是否私有。

 外部类访问内部类的成员属性和方法就需要通过内部类产生对象,通过对象来调用。

public class Outter {
    private String msg = "Outter中的msg属性";
    private static int age = 0;
    public void fun(){
        System.out.println("Outter的fum方法");
        Inner inner = new Inner();
        System.out.println(inner.innerMsg);
        inner.fun();
    }
    //-------------分割线---------------
    // 成员内部类
    class Inner{
        private String innerMsg = "Inner中的msg属性";
        public void fun(){
            System.out.println("-------------分割线---------------");
            System.out.println("Inner的fun方法");
            System.out.println(innerMsg);
            System.out.println(msg);

        }
    }
    //-------------分割线---------------
    public static void main(String[] args) {
        Outter outter = new Outter();
        outter.fun();
    }
}

内部类存在的原因

1.内部类和外部类可以方便的访问彼此的私有域(属性和方法)
   就是对于两者而已,没有什么秘密可言。但对其他类就不一定了,看内部类的修饰权限

⒉.内部类可以对外部类的外部完全隐藏(把内部类就当做外部类的属性来看待)


 

3.内部类可以变相实现多继承~~(了解即可,很少使用)

案例:在一个类里面搞两个内部类,让内部类继承,内部类跟外部类互通,外部类相当于达到了继承的效果,但是不推荐、


 

成员内部类

1.成员内部类∶在外部类的内部不使用static关键字定义的内部类就是成员内部类类比成员属性和成员方法

举例:就比如我们上面写的内部类就是

这个内部类跟 msg,age,这些属性是同级别的。


类比 成员属性和成员方法

成员内部类需要依赖外部类对象

先有外部类对象,才有内部类对象
相当于你想要往卡里存钱,前提你必须要有银行卡。

关于成员内部类产生对象的两种方式

1.在外部类的内部产生成员内部类对象∶在Outter的内部产生Inner对象就和普通类没啥区别

内部类名称  内部类引用  =  new内部类();
2.若内部类对外部可见(不是private修饰的内部类)在外部类的外部创建内部类对象

外部类名称.内部类名称内部类引用  =  new外部类().new内部类();

Outter.Inner inner = new Outter().new Inner();


注释:因为Inner内部类前面没有加任何修饰权限,所以是包访问权限。

私有内部类

在内部类前面加上修饰符 private 

 私有内部类,对于Outter类的外部完全隐藏,除了Outter类,外部完全无法使用Inner类

 注释:只有内部类就能用private修饰,外部类是不可以的。

            如果外部类都用private修饰的话,还有谁能找的到它?相当于废了。

⒉成员内部类需要依赖外部类的对象,先产生外部类对象,然后产生内部类对象

   类比成员属性或成员方法
 

知识回顾:

成员方法可以访问类中的 实例变量 和 静态变量 ,但是不能定义静态变量

静态方法  不可以访问非静态成员属性或方法

成员内部类可以直接访问外部类私有属性()

外部类名称.this 打印的就是外部类地址 

如果此时你想在内部类里面调用外部类同名的方法

注释:这样很容易死循环,递归调用。

所以这样我们产生内部类,使用内部类调用

提问: 成员内部类 能否访问外部类中的静态域

可以:还是那句话,把内部类看做是一个普通的成员方法或属性。

我们普通的成员方法里面都可以访问静态域,内部类当然也可以。因为成员内部类已经拥有外部类的对象,都有对象了,当然可以访问静态属性。

提问:成员内部类 能否在当前内部类中自己定义静态域?

不可以,那内部类当初普通的成员方法去想象即可。静态方法是不需要产生对象,通过类名称就可以访问的存在,和普通的方法都是必须通过产生的对象来调用访问。

核心:成员内部类必须要依赖外部类对象才能产生



 

静态内部类

使用static关键字定义在另一个类的内部的类 —— 静态方法或属性

区别:

和成员内部类最大的区别:静态内部类不需要外部类的对象,和外部类是一个相对独立的关系,只是套在外部类的内部定义而已~~

静态内部类只能访问外部类的静态域,没有外部类对象,无法直接访问外部类的成员域

 提问:静态内部类中能否定义自己的成员域?

 可以:静态内部类就是个普通类,只不过套在一个类的内部而已~

注释:主方法不就是 static 修饰的嘛~

成员内部类可以访问外部类的所有域(成员,静态),因为成员内部类依赖外部类的对象;

不能拥有自己的静态域

静态内部类可以拥有自己的成员域,但是不能直接访问外部类的成员域(没有外部类对象)

小总结

内部类:一个类嵌套定义在另一个类的内部

方法内部类(了解即可)

注释:可以把方法内部类类比于 局部变量

 定义在方法中的类.

注释:它和之前讲的普通代码块有点像。 

要点:

1. 不能用任何权限修饰符

因为出了这个方法对外部就完全不可见了,所以就没意义了。类比于局部变量。我们在一个普通的方法里面定义 int,double,String 时,前面从来都不会加上 public、private ...等等这些修饰符。 因为定义的变量在这个方法里面可能可见,但出了方法都是完全隐藏,或者说被销毁的数据。

2. 对外部类的外部完全隐藏

3. Test内部类要使用fun方法的形参或者局部变量,该变量必须为隐式的final声明

 原因:方法内部类要使用外部方法中的形参或者局部变量,只有读取权,无法修改

4.若方法内部类中读取了方法中的局部变量(形参或者局部变量)
这个局部变量就无法修改(不仅在内部类中没法改,在方法中也不能改)

在lnner中使用了 i 局部变量,这个变量隐式的final声明(编译之后相当于final int i)

 提问:在方法内部类Inney中能否定义static域?

注释:方法内部类就看做是外部方法的局部变量

不可以!你有见过在方法中定义的局部变量前面有static的吗?别说static了就连修饰符都没有!

5.在方法内部类中无法定义static域
 

注释:方法内部类是依赖外部方法而生产的,想绕过外部方法直接调用,无疑是错误的。

 

匿名内部类

定义在方法中(方法的形参或者实参) —— 实参用的最多

没有任何权限修饰符,甚至连类名称都没有的内部类
匿名内部类也是方法内部类的一种,最多用在方法形参中

 接口无法直接实例化对象的,因此我们此处其实new的是lMessage接口的子类只不过这个子类只在fun方法中使用一次

之前实现最大堆时,用的就是匿名内部类

Lambda表达式

 当Java发布到2008年的时候,Java已经走过了20个年份
Java的开发者发现,上古版本中(JDK1.0)的接口的子类都具备一个普通方法,这个方法,在接口中不存在

我想在接口拓展这个方法=》JDK8之前的接口都是抽象方法,所有子类都必须覆写该方法

函数式接口

Lambda表达式的前身 —— 匿名内部类


 

 Lambda表达式把匿名内部类中多余的new方法定义之类的全都省略了,只保留了方法的参数和方法体的实现!!

Lambda表达式的四种情况

对应抽象方法的四种分支

1.无返回值,无参数

 注释: () 这个括号就是test方法的括号,{ } 这个大括号就是test的方法体(方法内容)

2.无返回值,有参数

 这里运行输出的结果为 30

规则2.若方法的参数只有一个,可以省略小括号

规则3.可以省略Lambda表达式中参数的类型,若省略类型,都需要省略。

3.有返回值,无参数

规则4.若抽象方法存在返回值且覆写的方法体只有一行,此时方法体的大括号,return都能省略
 

4.有返回值有参数
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值