[17]内部类

【成员内部类】

内部类:将一个类在另一个类中定义。

class Outer8{
    class Inner{
        
    }
}

Inner就是内部类。而编译后,会在目录中生成两个class文件

Outer8.class就是外部类。

Outer8$Inner.class就是Inner类在Outer8类中。

访问方式:

内部类可以访问外部类的所有成员,包括私有。

class Outer{
   private int i=3;
    class Inner{
        int i2=i;
    }
}

外部类若要访问内部类,内部类作为外部类的成员,所以应该先创建外部类的实例。

class Outer{
    class Inner{
        
    }
    public Inner getInstance(){
        return new Outer().new Inner();
    }
}

非静态内部类中不允许定义静态成员,仅允许定义静态常量 static final

若要定义静态成员,内部类必须是静态成员。

【例子】

class Outer{
    int num=3;
    class Inner{
        int num=4;
        public void method(){
            int num=5;
            System.out.println(num);
            System.out.println(this.num);
            System.out.println(Outer.this.num);
        }
    }
}

 如果什么都不加就是访问局部变量

如果要访问内部类当前对象的,则是this.num

如果要访问外部类成员,则是Outer.this.num

【局部内部类】

将类定义在方法区或是作用域中。

class Outer{
    public void method(){
        class Inner{}
    }
}

局部内部类不允许被成员修饰符修饰,类似于public,static

局部内部类访问内部类中的成员,只允许访问被final修饰的局部变量

原因:

若假设可以访问。

1.main()压栈执行,实例化Outer对象。属性为obj。调用method()

2.method()压栈,显示初始化变量i,o=new Inner(),加载Inner类,调用构造函数,创建对象。i释放内存

3.method()弹栈,调用method3(), obj=new Inner()相当于Object obj=new Inner();多态

4.调用method2()中的方法需要输出打印i,i早已释放内存,怎么调用???

class Outer{
    Object obj;
    public void method(){
        int i=3;
        class Inner{
            public void method2(){
                System.out.println(i);
            }
        }
       obj= new Inner();
    }

    public void method3(){
        obj.method2():
    }
}

class Demo{
    public static void main(String[] args){
        Outer o=new Outer();
        o.show();
        o.method3();
    }
}

【匿名内部类】

内部类是可以继承父类和实现接口的。

interface B{
    public abstract void method();
}

class A{
    public void method2(){}
}

class Outer{
    class Inner extends A implements B{
        @override
        public void method(){}
    }
}

为了简化代码,就有了匿名内部类。

interface Inter{
    public abstract void method();
}

class Outer{
    public void method(){
        new Inter(){
            @override
            public void method(){}
        };
    }
}

【匿名内部类代码体现】

父类/接口 引用变量=new 父类/接口();

 【匿名内部类的条件、前提】

匿名内部类必须由继承父类或是实现接口

 

匿名内部类类似于匿名对象,然而一般匿名内部类是用来简写代码,不知道匿名内部类叫什么,所以通过多态的原理

利用父类创建对象,并且重写方法。

【例子】

class Outer{
    //编译通过
    new Object(){
        public void show(){}
    }.show();
    //编译失败
    Object o=new Object(){
        public void show(){}
    };//.show();
    o.show();//报错
}

为什么一个能通过,另一个却不能通过呢?

前者是因为创建子类对象,却没有父类引用,所以对象本身重写方法,所以不报错。

而后者是因为创建子类对象,父类引用,而父类中并没有show()这个方法,一调用就会报错。

而如果不调用,是不会报错的。

【静态内部类】

静态内部类就是在成员内部类前加static,静态内部类不属于外部类。可以当成另一个外部类。因为不依赖于外部类。并且不能访问父类的非静态成员。

并且非静态内部类不能访问静态成员,可能编译器会通过。

考虑这么一个情况:如果非静态内部类还没被实例化,直接调用了静态成员。但是静态成员是随着类的加载而加载。却可以调用静态成员。矛盾

class Outer{
    static int num=3;
    int num2;
    
    static void method2(){
        System.out.println(num);
    }

    static class Inner{
        void method(){
            //可以访问外部类的静态成员,但不能访问外部类的非静态成员
            System.out.println(num);//编译通过
            System.out.println(num2);//报错
        }
    }

    class Inner2{
       method();//无法做到
    }
}

外部进行访问静态内部类的方式

class Outer{
    static class Inner{
        public static void show(){}
        public void show2(){}
    }
    
}

class Demo{
    public static void main(String[] args){
        //调用静态内部类的静态方法
        Outer.Inner.show();
        //1.若要调用静态内部类的非静态方法,可以不依赖外部类直接创建实例并调用非静态方法
        new Inner().show();
        //2.或是先给引用变量
        Outer.Inner i=new Inner();
        i.show();
    }
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值