目录
所谓的内部类就是将一个类嵌套到另一个类的内部的操作
核心思路:就把内部类看成当前类中一个普通属性来看待
类似于 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.有返回值有参数