内部类
内部类初体验
public class InnerClass {
private int a = 100 ;
public void test ( ) {
System. out. println ( "这是普通方法!" ) ;
}
static class In01 {
private int b = 200 ;
public void test ( ) {
System. out. println ( "这是一个内部类" ) ;
System. out. println ( b) ;
}
}
}
public class Test extends InnerClass. In01 {
public static void main ( String[ ] args) {
InnerClass. In01 in01 = new InnerClass. In01 ( ) ;
InnerClass innerClass = new InnerClass ( ) ;
innerClass. test ( ) ;
Test test = new Test ( ) ;
test. test ( ) ;
}
public void fuck ( ) {
InnerClass. In01 in01 = new InnerClass. In01 ( ) ;
class Td {
}
}
}
1.成员内部类
a.成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。
b.当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:外部类.this.成员变量 / 外部类.this.成员方法
c.在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问
d.创建成员内部类的对象,前提是必须存在一个外部类的对象
1).Outter.Inner inner = outter.new Inner(); //必须通过Outter对象来创建
2).Outter.Inner inner1 = outter.getInnerInstance();//方式二
public class Demo01 {
private String test = "Demo01" ;
public Demo01 ( ) {
}
public void test ( ) {
System. out. println ( "Demo01:test" ) ;
}
public class Demo01In {
private String testIn = "Demo01In" ;
private String test = "Demo01In" ;
public void testIn ( ) {
System. out. println ( "Demo01In:testIn" ) ;
System. out. println ( testIn) ;
System. out. println ( Demo01. this . test) ;
}
}
public class Demo01In2 {
}
}
public class Test {
public static void main ( String[ ] args) {
Demo01 demo01 = new Demo01 ( ) ;
Demo01. Demo01In demo01In = demo01. new Demo01In ( ) ;
demo01In. testIn ( ) ;
Demo01. Demo01In demo01In2 = new Demo01 ( ) . new Demo01In ( ) ;
Test test = new Test ( ) ;
}
}
2.静态内部类:静态内部类是不需要依赖于外部类的,不能使用外部类的非static成员变量或者方法
a.静态内部类不持有指向外部类对象的引用
public class Demo02 {
private String test = "Demo02" ;
public void test ( ) {
System. out. println ( test) ;
}
public static class Demo02In {
private String testIn = "Demo02In" ;
public void testIn ( ) {
System. out. println ( testIn) ;
Demo02 demo02 = new Demo02 ( ) ;
System. out. println ( demo02. test) ;
}
}
}
public class Test extends Demo02. Demo02In {
public static void main ( String[ ] args) {
Demo02. Demo02In demo02In = new Demo02. Demo02In ( ) ;
demo02In. testIn ( ) ;
Test test = new Test ( ) ;
test. testIn ( ) ;
}
}
3.局部内部类:局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。
注:局部内部类就像是方法里面的一个局部变量一样,是不能有 public、protected、private 以及 static 修饰符的。
public class Demo03 {
private String test = "Demo03" ;
public void test ( final int tag) {
int num = 0 ;
class Demo03In {
private String testIn = "Demo03In" ;
private String test = "Demo03In" ;
public void testIn ( ) {
System. out. println ( testIn) ;
System. out. println ( Demo03. this . test) ;
System. out. println ( num) ;
System. out. println ( tag) ;
}
}
Demo03In demo03In = new Demo03In ( ) ;
demo03In. testIn ( ) ;
}
}
public class Test {
public static void main ( String[ ] args) {
Demo03 demo03 = new Demo03 ( ) ;
demo03. test ( 10 ) ;
}
}
4.匿名内部类:
1.匿名内部类能够在实现父类或者接口中的方法情况下同时产生一个相应的对象,但是前提是这个父类或者接口必须先存在才能这样使用
2.匿名内部类不能有访问修饰符和 static 修饰符的。
3.匿名内部类是唯一一种没有构造器的类。正因为其没有构造器,所以匿名内部类的使用范围非常有限,大部分匿名内部类用于接口回调。匿名内部类在编译的时候由系统自动起名为 Outter$1.class。一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。
4.应用:编写事件监听的代码时,使用匿名内部类不但方便,而且使代码更加容易维护。
public interface TestInterface {
void test ( ) ;
}
public class TestDemo implements TestInterface {
@Override
public void test ( ) {
System. out. println ( "test:Demo" ) ;
}
}
public class Demo04 {
private TestInterface interface1 = new TestDemo ( ) ;
private TestInterface interface2 = new TestInterface ( ) {
@Override
public void test ( ) {
System. out. println ( "1111" ) ;
}
} ;
public static void main ( String[ ] args) {
Demo04 demo04 = new Demo04 ( ) ;
demo04. interface1. test ( ) ;
demo04. interface2. test ( ) ;
demo04. callBack ( demo04. interface1) ;
demo04. callBack ( demo04. interface2) ;
TestInterface testInterface = new TestInterface ( ) {
private int num = 0 ;
@Override
public void test ( ) {
System. out. println ( "22222" ) ;
}
} ;
demo04. callBack ( testInterface) ;
demo04. callBack ( new TestInterface ( ) {
@Override
public void test ( ) {
System. out. println ( "3333" ) ;
}
} ) ;
}
public void add ( int a) {
System. out. println ( a) ;
}
public void callBack ( TestInterface testInterface) {
testInterface. test ( ) ;
}
}
5.扩:
a.为什么局部内部类和匿名内部类只能访问局部final变量?
对于引用类型的变量,是不允许指向新的对象,会造成数据不一致性
b.为什么成员内部类可以无条件访问外部类的成员?
编译器会默认添加一个参数,该参数的类型为指向外部类对象的一个引用,所以成员内部类中的 Outter this&0 指针便指向了外部类对象,因此可以在成员内部类中随意访问外部类的成员
c.内部类用来继承
1).成员内部类的引用方式必须为 Outter.Inner
2).构造器中必须有指向外部类对象的引用,并通过这个引用调用super()
6.使用内部类的优势
1.每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。内部类使得多继承的解决方案变得完整。
2.方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏。
3.方便编写事件驱动程序。
4.方便编写线程代码