首页 > 代码库 > Java内部类详解
Java内部类详解
1:形式参数和返回值的问题(理解)
(1)形式参数:
类名:需要该类的对象
抽象类名:需要该类的子类对象
接口名:需要该接口的实现类对象
(2)返回值类型:
类名:返回的是该类的对象
抽象类名:返回的是该类的子类对象
接口名:返回的是该接口的实现类的对象
(3)链式编程
对象.方法1().方法2().......方法n();
这种用法:其实在方法1()调用完毕后,返回一个对象;
方法2()调用完毕后,返回一个对象。
B:局部内部类:在方法里面
(4)成员内部类
A:private 为了数据的安全性
B:static 为了访问的方便性
成员内部类不是静态的:
外部类名.内部类名 对象名 = new 外部类名().new 内部类名();
成员内部类是静态的:
外部类名.内部类名 对象名 = new 外部类名.内部类名();
(5)成员内部类的面试题(填空)
(6)局部内部类
A:局部内部类访问局部变量必须加final修饰。
B:为什么呢?
因为局部变量使用完毕就消失,而堆内存的对象并不会立即消失。
该对象还是用该变量,而变量已经没有了。
为了让该值还存在,就加final修饰,让它变成常量
通过反编译工具我们看到了,加入final后,堆内存直接存储的是值,而不是变量名
(7)匿名内部类(掌握)
B:前提
存在一个类或者接口
C:格式:
new 类名或者接口名() {
重写方法;
}
D:本质:
其实是继承该类或者实现接口的子类的匿名对象
(8)匿名内部类在开发中的使用
我们在开发的时候,会看到抽象类,或者接口作为参数。
而这个时候,我们知道实际需要的是一个子类对象。
如果该方法仅仅调用一次,我们就可以使用匿名内部类的格式简化。
(1)形式参数:
类名:需要该类的对象
抽象类名:需要该类的子类对象
接口名:需要该接口的实现类对象
(2)返回值类型:
类名:返回的是该类的对象
抽象类名:返回的是该类的子类对象
接口名:返回的是该接口的实现类的对象
(3)链式编程
对象.方法1().方法2().......方法n();
这种用法:其实在方法1()调用完毕后,返回一个对象;
方法2()调用完毕后,返回一个对象。
方法n()调用完毕后,可能是对象,也可以不是对象。
2:内部类(理解)
(1)把类定义在另一个类的内部,该类就被称为内部类。
举例:把类B定义在类A中,类B就被称为内部类。
(2)内部类的访问规则
A:可以直接访问外部类的成员,包括私有
B:外部类要想访问内部类成员(包括私有成员),必须创建对象
class Outer { private int num = 10; class Inner { public void show() { System.out.println(num); } } public void method() { <span style="white-space:pre"> </span>//外部类访问内部类 Inner i = new Inner(); i.show(); } }(3)内部类的分类
class Outer { private int num = 10; //成员位置 class Inner { } public void method() { //局部位置 class Inner { } } }A:成员内部类:在成员位置
/* 成员内部类: 如何直接访问内部类的成员。 外部类名.内部类名 对象名 = 外部类对象.内部类对象; */ class Outer { private int num = 10; class Inner { public void show() { System.out.println(num); } } } class InnerClassDemo3 { public static void main(String[] args) { //需求:我要访问Inner类的show()方法 //格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象; Outer.Inner oi = new Outer().new Inner(); oi.show(); } }
B:局部内部类:在方法里面
(4)成员内部类
A:private 为了数据的安全性
B:static 为了访问的方便性
成员内部类不是静态的:
外部类名.内部类名 对象名 = new 外部类名().new 内部类名();
成员内部类是静态的:
外部类名.内部类名 对象名 = new 外部类名.内部类名();
/* 成员内部类的修饰符: private 为了保证数据的安全性 static 为了方便访问数据 注意:静态内部类访问的外部类数据必须用静态修饰。因为静态的数据是类加载时就分配内存空间了 案例:我有一个人(人有身体,身体内有心脏。) class Body { private class Heart { public void operator() { System.out.println("心脏"); } } public void method() { if(...) {//加判断,符合条件既可以访问 Heart h = new Heart(); h.operator(); } } } 按照我们刚才的讲解,来使用一下 Body.Heart bh = new Body().new Heart(); bh.operator(); //加了private后,就不能被访问了,那么,怎么玩呢?<span style="color:#ff0000;">通过外部类调用方法来访问private内部类 Body b = new Body(); b.method();</span> */ class Outer { private int num = 10; private static int num2 = 100; //内部类用静态修饰是因为内部类可以看作是外部类的成员 public static class Inner { public void show() {//非静态 //System.out.println(num); System.out.println(num2); } public static void show2() {//静态 //System.out.println(num); System.out.println(num2); } } } class InnerClassDemo4 { public static void main(String[] args) { //成员内部类被静态修饰后的访问方式是: //格式:外部类名.内部类名 对象名 = new 外部类名.内部类名(); //因为静态是可以通关类名直接访问的,所以只需要创建内部类对象即可 <span style="color:#ff0000;">Outer.Inner oi = new Outer.Inner();</span> oi.show(); oi.show2(); //show2()的另一种调用方式 Outer.Inner.show2(); } }
(5)成员内部类的面试题(填空)
输出:30,20,10 class Outer { private int num = 10; class Inner { private int num = 20; public viod show() { int num = 30; System.out.println(num);//30 System.out.println(this.num);//20 <span style="color:#ff0000;">System.out.println(new Outer().num);//10 System.out.println(Outer.this.num);//面试一般面试这种,10</span> } } }
(6)局部内部类
A:局部内部类访问局部变量必须加final修饰。
B:为什么呢?
因为局部变量使用完毕就消失,而堆内存的对象并不会立即消失。
该对象还是用该变量,而变量已经没有了。
为了让该值还存在,就加final修饰,让它变成常量
通过反编译工具我们看到了,加入final后,堆内存直接存储的是值,而不是变量名
/* 局部内部类 A:可以直接访问外部类的成员 B:<span style="color:#ff0000;">在局部位置,可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能</span> 面试题: 局部内部类访问局部变量的注意事项? A:局部内部类访问局部变量必须用final修饰 B:为什么呢? 局部变量是随着方法的调用而调用,随着调用完毕而消失。 而堆内存的对象并不会立即消失。所以,我们加final修饰。 加入final修饰后,这个变量就成了常量。既然是常量。你消失了。 我在内存中存储的是数据20,所以,我还是有数据在使用。 */ class Outer { private int num = 10; public void <span style="color:#ff0000;">method()</span> { <span style="color:#ff0000;">final</span> int num2 = 20;//final类型修饰 <span style="color:#ff0000;">class Inner</span> { public void show() { System.out.println(num); //从内部类中访问本地变量num2; 需要被声明为最终类型 System.out.println(num2);//20 } } //怎么使用局部内部类呢,这和成员内部类的使用方法不一样,需要在局部位置,创建局部<span style="font-family: Arial, Helvetica, sans-serif;">内部类对象,通过对象调用局部内部类方法,来使用局部内部类功能</span><span style="font-family: Arial, Helvetica, sans-serif;"> </span>
<span style="color:#ff0000;">Inner i = new Inner(); i.show();</span> } } class InnerClassDemo5 { public static void main(String[] args) { Outer o = new Outer(); o.method(); } }
(7)匿名内部类(掌握)
B:前提
存在一个类或者接口
C:格式:
new 类名或者接口名() {
重写方法;
}
D:本质:
其实是继承该类或者实现接口的子类的匿名对象
(8)匿名内部类在开发中的使用
我们在开发的时候,会看到抽象类,或者接口作为参数。
而这个时候,我们知道实际需要的是一个子类对象。
如果该方法仅仅调用一次,我们就可以使用匿名内部类的格式简化。
<span style="white-space:pre"> </span>interface Person { public abstract void study(); } class PersonDemo { public void method(Person p) { p.study(); } } class PersonTest { public static void main(String[] args) { PersonDemo pd = new PersonDemo(); pd.method(new Person() { public void study() { System.out.println("好好学习,天天向上"); } }); } }<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span>(9)匿名内部类的面试题(补齐代码)
<span style="white-space:pre"> </span>interface Inter { void show(); } class Outer { //补齐代码 } class OuterDemo { public static void main(String[] args) { Outer.method().show(); //"HelloWorld" } }补全的代码为:
<pre name="code" class="java">/*
1:Outer.method()可以看出method()应该是Outer中的一个静态方法。 2:Outer.method().show()可以看出method()方法的返回值是一个对象。 又由于接口Inter中有一个show()方法,所以我认为method()方法的返回值类型是一个接口。
*/
public static <span style="color:#ff0000;">Inter</span> method() { <span style="color:#ff0000;">return new Inter() { public void show() { System.out.println("HelloWorld"); } };</span> }
Java内部类详解
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。