3、内部类啥时候用?
当描述事物时,事物的内部还有事物,该事物用内部类来描述。
因为内部事物在使用外部事物中的内容。
比如,假设我现在描述人体,你描述人体的时候,就没有年龄等属性。
对于心脏而言,属性非常多,属性一多,是不是要进行封装啦?
一封装,是不是类啦?
class Body {} class XinZang {}
如下,XinZang类在里面
class Body { class XinZang { } }
这样是不是更好一些,为啥?跟你讲你那心脏是不是在访问你身体里的其他器官,注意人体里会定义其他东西,而如果XinZang在外面是不是需要创建人体对象,是不是不合适。放在里面直接可以访问人体中的其他东西,明白了吧。
当这类事物需要直接访问外部事物其它东西时,放在这个事物内部,这样代码的设计是最优的。
非要把心脏放在外面也可以,但别扭。
后面讲集合的时候,我们单独学习,内部类单独设计,
java中的,把它掰开给你说,就o了,而且那还有个经典比喻,
这就不先透露了,说了那还能经典吗,就不是经典了。
心脏不需要对外透露,前面加private。私有了外界就访问不到了,
此时提供个访问方式
class Body { private class XinZang { } public void show() { new XinZang(). ; } }
你会发现,刚才我们写的内部类,这些内部类是不是都定义
在外部类成员位置上了。只有在成员位置上时才能被私有、static修饰,
一般内部类不被public修饰,有没有这种情况,当然也有,
比较特殊的情况会出现,当然这是接口不是一般类了。
下面如果内部类是局部成员,
修饰符不可修饰局部内部类,且内部类里面不可定义静态成员。
如果要访问method()中的局部成员,
class Outer { int x=3; void method() { int y=6; class Inner { int x=5; void function() { System.out.println(y); } } new Inner().function(); } }
出现:
内部类定义在局部时,
1,不可以被成员修饰符修饰
2,可以直接访问外部类中的成员,因为还持有外部类中的引用。
但是不可以访问它所在的局部中的变量(亲测JAVA8居然可以)。
只能访问被final修饰的局部变量。
class Outer { int x=3; void method() { int y=6; class Inner { int x=5; void function() { System.out.println(y); } } new Inner().function(); } }
会出现:
所以,
void method() { final int y=6; class Inner { int x=5; void function() { System.out.println(y); } } new Inner().function(); }
主函数在栈内存中,堆内存中是对象。
成员变量有默认值,不赋值可以参与运算,因为在堆内存中;
而局部变量在栈内存中,没有默认值,初始化后,才可参与运算。
4、匿名内部类
1,匿名内部类其实就是内部类的简写格式。
2,定义匿名内部类的前提:
内部类必须是集成一个类或者实现接口。
3,匿名内部类的格式:new 父类或者接口(){定义子类的内容}.调用方法();
4,匿名内部类就是一个匿名子类对象,而且这个对象有点胖,可以理解为内容的对象。
5,匿名内部类定义方法不宜过多。
<script src="https://code.csdn.net/snippets/s1G4h1J279m90582r6h5.js"></script>
不写匿名,用注释部分也行。但
开发当中,如果你要玩AWT的话,这样的写法非常常见,因为它简单。
如果重复调用对象内部方法,按照上面写是不是很麻烦。
给对象起个名字应用多态那就解决这个问题了,内部类写法
AbsDemo abs=new AbsDemo() //运用多态向上转型 { void show() { System.out.println("x==="+x); } }; abs.show();
但
AbsDemo abs=new AbsDemo() //运用多态向上转型 { void show() { System.out.println("x==="+x); } void abc() { System.out.println("abc:"); } }; abs.abc();
这不行,一般这么用没多大意义,因为匿名对象就是为了简化书写覆盖父类方法。
匿名内部类是有局限的,
1,你直接调用自己的方法还不行
2,你也不能重载动作
3,如果父类的抽象方法非常多,匿名函数要覆写阅读性非常烂。
练习:
面试题:
class InnerClassTest { public static void main(String[] args) { new Object() //在外面没有定义任何父类和接口,也可使用匿名内部类 { public void function() { System.out.println("x"); } }.function(); } }