About Me
欢迎各位读者访问,大家一起学习。
优秀是一种习惯♡♡♡
做更好的自己!
本人见识有限,写到博客难免有错误或疏忽的地方,还望各位大佬多多指点,在此表示感激不尽。♡♡♡
一:了解内部类
内部类:就是一个类中定义一个类,也就是在A类的内部定义一个B类,B类就称为内部类。如同一个人是由大脑,肢体,器官等组合而成,而内部类就相当于某个器官之一,例如心脏,心脏有属性和方法(血液 、跳动)所以就得用一个类来表示,而心脏又在人体当中,所以内部类在外部类中。
二:内部类分类
1. 成员内部类
成员内部类是是最普通的内部类,定义位于一个类的内部。
1.1 格式:
外部类名.内部类名 对象名 = new 外部类对象().new 内部类对象();
外部类名:是为什么标明生成的内部类对象在哪个外部类当中。
/**
* @author Tornado
* @date 2021/11/14 21:24
*/
public class Test {
public static void main(String[] args) {
//创建内部类对象
Out.In oi = new Out().new In();
oi.method();
}
}
//外部类
class Out {
private int age = 10;
//内部类
class In {
//定义一个method()方法
public void method() {
//内部类可以访问外部类的成员变量,私有的也可以。
System.out.println(age);
}
}
}
1.2 思考?
上面这个内部类严重破坏了良好的代码结构,为什么还要使用内部类呢?
使用内部类这种技术,可以隐藏细节和内部结构,封装性更好,内部类可以随意访问外部类的成员变量,外部类的私有成员变量,内部类也可以访问。而不用生成外部类对象,这也就是内部类的优点。就如同心脏可以直接访问身体的血液,而不用医生抽血。
1.3 变量如何访问?
/**
* @author Tornado
* @date 2021/11/14 21:24
*/
public class Test {
public static void main(String[] args) {
//创建内部类对象
Out.In oi = new Out().new In();
//调用method()方法
oi.method();
}
}
//外部类
class Out {
private int age = 30;
//内部类
class In {
private int age = 20;
//定义一个method()方法
public void method() {
int age = 10;
System.out.println("局部变量:" + age);
System.out.println("内部类变量:" + this.age);
System.out.println("外部类变量:" + Out.this.age);
}
}
}
运行结果
内部类在没有同名的局部变量和成员变量的情况下,内部类会直接访问外部类的成员变量。
局部变量:10
内部类变量:20
外部类变量:30
2. 局部内部类
局部内部类就是在一个外部类的方法中写内部类。也就是把内部类写到了外部类的成员方法中。它和成员内部类的区别就在于访问仅限于方法内或该作用域内。注意:局部内部类中就像是一个方法中定义了一个局部变量一样,是不能有public ,private ,static,protected权限修饰符的。
/**
* @author Tornado
* @date 2021/11/14 21:24
*/
public class Test {
public static void main(String[] args) {
//创建外部类对象
Out out = new Out();
//调用成员方法method()
out.method();
}
}
//外部类
class Out {
private int age = 30;
public void method() {
//局部内部类不能写权限修饰符修饰类
class In {
private int age = 20;
//定义一个method()方法
public void method() {
System.out.println("内部类的方法");
}
}
//创建局部内部类对象
In in = new In();
//调用method()方法
in.method(); //内部类方法
}
}
2.1 思考?
如何将局部内部类的对象抛到外界使用?
/**
* @author Tornado
* @date 2021/11/15 18:48
*/
public class Test {
public static void main(String[] args) {
//如何把Inner扔到这里用
}
}
class Outer{
//成员方法
public void show(){
class Inner{
public void method(){
System.out.println("内部类的method方法");
}
}
Inner inner = new Inner();
inner.method();
}
}
根据上面程序可以看出成员内部类不能直接使用Inner对象,而是要通过外部类调用成员方法show()才可以用,那有什么办法可以在外界使用Inner对象呢???看下面这个程序
/**
* @author Tornado
* @date 2021/11/15 18:48
*/
public class Test {
public static void main(String[] args) {
//如何把Inner扔到这里用
//创建外部类Outer对象
Outer outer = new Outer();
//调用show()方法,返回的值就是Inner对象
Face inner = outer.show();
System.out.println(inner);//com.ljf666.test15.Outer$1Inner@36d64342
inner.method();//内部类的method方法
}
}
class Outer{
//成员方法【返回值:Face】
public Face show(){
//内部类实现接口
class Inner implements Face{
//重写接口中的method()方法
public void method(){
System.out.println("内部类的method方法");
}
}
//创建Inner对象
Inner inner = new Inner();
//返回inner
return inner;
}
}
//定义一个接口Face
interface Face{
//定义一个抽象方法method()
void method();
}
既然局部内部类无法直接使用内部类对象,我们可以通过外界定义一个接口,并让内部类实现这个接口,然后将外部类的成员方法变为带有返回值的,返回值为inner对象,然后内部return返回inner对象,外界就可以通过调用方法而调用到inner对象。即可在外界调用到method()方法。
3. 静态内部类
静态内部类也是在一个类的内部定义了一个类,只不过是在类的前面加上了static关键字,静态内部类是不需要外部类的,和类的静态成员变量有点类似,静态内部类不能使用外部类中的非static修饰的成员。
/**
* @author Tornado
* @date 2021/11/15 19:18
*/
public class Test {
public static void main(String[] args) {
//创建静态内部类的对象
Outer.Inner oi = new Outer.Inner();
//调用内部类中的方法
oi.methodInner(); //静态内部类的方法10
}
}
class Outer{
//定义一个成员方法
public void method(){
System.out.println("外部类的成员方法");
}
//定义一个静态成员变量
static int a = 10;
//定义一个静态内部类
static class Inner{
public void methodInner(){
//method(); 编译报错,静态的无法使用非静态的。
System.out.println("静态内部类的方法"+a);
}
}
}
4. 匿名内部类
4.1:本质
匿名内部类本质上是一个特殊的局部内部类,在一个接口,将继承\实现,方法重写,创建对象,放到了一步进行。匿名内部类是用的最多的
4.2:格式
new 类名 \ 接口名(){
重写方法
}
4.3:实例
4.3.1:格式一
/**
* @author Tornado
* @date 2021/11/15 0:49
*/
public class Test01 {
public static void main(String[] args) {
//使用匿名内部类的方式创建对象
A a = new A() {
@Override
public void method() {
System.out.println("这是使用匿名内部类的方式实现的!!!");
}
};
//调用method()方法
a.method();
}
}
//定义一个接口A
interface A {
//定义一个方法method()
void method();
}
4.3.2:格式二
/**
* @author Tornado
* @date 2021/11/15 0:49
*/
public class Test01 {
public static void main(String[] args) {
//使用匿名内部类【格式二】
new A() {
@Override
public void method() {
System.out.println("这是使用匿名内部类的方式实现的!!!");
}
//调用method()方法
}.method();
}
}
//定义一个接口A
interface A {
//定义一个方法method()
void method();
}
4.4: 开发中的使用
当一个接口中只有一个抽象方法的时候,就可以使用匿名内部类font>的方式比较合适,因为这样比较方便,少建java文件,少些class类。但是当一个接口中有多个抽象方法的时候,就不如新建一个java文件,实现这个接口。
/**
* @author Tornado
* @date 2021/11/15 10:02
*/
public class TestSwimming {
public static void main(String[] args) {
//调用方法并使用匿名内部类的方式传入一个参数列表
goSwimming(new Swimming() {
//重写接口中的swim()方法
@Override
public void swim() {
System.out.println("我们一起游泳吧!!!");
}
});
}
//定义一个static方法goSwimming:【返回值:void 方法名:goSwimming 参数列表:Swimming swmming】
public static void goSwimming(Swimming swimming) {
//调用匿名内部类重写后swim()方法
swimming.swim();
}
}
//定义一个接口Swimming
interface Swimming {
//抽象方法swim();
void swim();
}
三:深入理解内部类
1. 为什么成员内部类可以无条件访问外部类?
成员内部类可以无条件的访问外部类,我们可以从反编译字节码上看。
1.1 代码
public class Test {
public static void main(String[] args) {
//创建静态内部类的对象
Outer.Inner oi = new Outer.Inner();
//调用内部类中的方法
oi.methodInner(); //静态内部类的方法10
}
}
class Outer{
//定义一;个成员方法
public void method(){
System.out.println("外部类的成员方法");
}
//定义一个静态成员变量
static int a = 10;
//定义一个静态内部类
static class Inner{
public void methodInner(){
//method(); 编译报错,静态的无法使用非静态的。
System.out.println("静态内部类的方法"+a);
}
}
}
1.2 编译后的.class文件
编译器会默认为成员内部类添加一个指向外部类对象的引用
2. 静态内部类有特殊的地方吗?
静态内部类是不依赖外部类的,也就是说可以在不创建外部类的情况下,创建内部类对象。
四:内部类的使用场景
1. 场景和好处
方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏。
每个内部类都能独立继承一个接口的实现。内部类的存在使得java的多继承机制变的完善。
方便编写事件驱动程序
方便编写线程代码
不要在最能吃苦的年纪选择了安逸!!! — Tornado♥