Java基础:内部类

一.概述

将类写在其他类的内部,也可以写在其他类的成员位置和局部位置,这种类就被称为内部类,其他类也被称为外部类

在描述事物时,若一个事物内部还包含其他的事物,例如汽车中的发动机,就可以用内部类来描述

class 汽车{

        class 发动机{

        }

}

二.内部类的特点

内部类提供了更好的封装,只有外部类可以访问内部类

内部类可以独立继承一个接口,不受外部类是否继承接口的影响

内部类可以直接访问外部类的成员,包括私有private

外部类想要访问内部类的成员,必须创建对象

在外部类中,即使内部类中用private修饰的成员,也可以在外部类中以内部类对象.成员的方式访问

private修饰内部类,则外部类以外不能访问,只能在外部类访问

三.内部类的分类

内部类分为成员内部类与局部内部类

其次还有匿名内部类和静态内部类

定义内部类时,就是一个正常定义类的过程,包含各种修饰符、继承、实现关系等

四.成员内部类

1.定义

定义在外部类中的成员位置。与类中的成员变量相似,可通过外部类.对象进行访问

访问方式:外部类名.内部类名 变量名=new 外部类名().new 内部类名()

class Body{

        private boolean life=true;

        public class Heart{

                public void jump(){

                        System.out.println("心脏扑通扑通跳");

                               System.out.println("生命状态"+life);

                }

        }

}

public static void main(String[] args){

        Body.Heart bh=new Body().new Heart();

        bh.jump();

}

3.成员内部类的同名变量调用:

public class Outer{

        int i=1;

        class Inner{

                int i=2;

                public void inner(){

                        int i=3;

                        System.out.println(Outer.this.i);

                }

        }

}

五.局部内部类

1.概述

局部内部类,定义在外部类方法中的局部位置。与访问方法中的局部变量相似,可以调用方法进行访问

可以直接访问外部类成员

局部内部类,只能在方法体中使用

局部类不能加访问修饰符,因为他们不是类成员

访问方式:在外部类方法中,创建内部类对象进行访问

2.例子

class Party{

        public void PuffBall(){

                class Ball{

                        public void puff(){

                                System.out.println("气球膨胀了");

                         }

                }

        new.Ball().puff();

        }        

}

public static void main(String[] args){

        Party p=new Party();

        p.PuffBall();

}

3.局部内部类访问局部变量的注意事项:

局部内部类访问局部变量必须用final修饰

jdk8或者更高版本,不要求被局部内部类所访问的局部变量一定要加final

但是编译器会自动给局部变量加上final

加final的原因:

因为局部变量会随着方法的调用和结束而存亡

而局部对象并没有立刻从堆内存中消失,还需要使用该变量,使用final修饰后,在堆内存中存储的实际上是一个常量值。

六.匿名内部类

1.概述

就是一个没有名字的局部内部类

匿名内部类是创建某个类型子类对象的快捷方式

定义一个内部类(成员内部类,局部内部类)没有名字,意味着类不能通过名字来复用,只能在类定义的时候被使用一次

2.特点

匿名内部类没有修饰符

匿名内部类必须继承一个类或者实现一个接口

这里的类可以是具体类也可以是抽象类

匿名内部类中不能存在任何静态成员或方法

匿名内部类没有构造方法,因为没有类名

匿名内部类为局部内部类,所以局部内部类的所有限制同样生效

匿名内部类不能是抽象的,必须实现继承的类或接口的所有抽象方法

3.格式:

new 父类或接口(){

        //进行方法重写        

};

4.匿名内部类如果不定义变量引用,则就是匿名对象

pubic abstract class Person{

        public abstract void eat();

}

new Person(){

        public void eat(){

                System.out.println("我吃了");

        }

}.eat();

5.匿名内部类的使用:

一般使用匿名内部类的场景是,要继承或实现的接口只有一个抽象方法,比如添加一个监听器:

public class Button{

        public void click(){

                //匿名内部类,实现的是ActionListener接口

                new ActionListener(){

                        public void onAction(){

                                System.out.println("click action...");

                        }

                }.onAction();

        }

        //匿名内部类必须继承或实现一个已有的接口

        public interface ActionListener{

                public void onAction();

        }

        public static void main(String[] args){

                Button button=new Button();

                button.click();

        }

}

其次,当方法的形式参数是一个接口时,在该方法传递实际参数时,实际传递的是一个接口的子类对象。

传递的这个实际参数,就可以用匿名内部类来代替

public class AnoyInnerDemo2{

        public static void main(String[] args){

                //1.利用常规方式调用input方法

                //A a=new A();

                //input(new A());

                //2.利用匿名内部类

                input(new Ordinary(){

                                public void toDo(){

                                        System.out.println("inner class todo");

                                }

                });

        }

        //接收接口类型形式参数的方法

        public static void input(Ordinary o){

                o.toDo();

        }

}

//接口

interface Ordinary{

        void toDo();

}

class A implements Ordinary{

        public void toDo(){

                System.out.println("class A todo");

        }

}

七、静态内部类

1. 概述

  • 使用static修饰的 成员内部类 我们称之为静态内部类
  • 静态内部类的创建是不需要依赖于外部类,可以直接创建

2. 访问特征:

  • 对于 静态内部类 而言,它不能访问外部类中 非静态的 成员变量和成员方法
  • 在 外部类中 访问,静态内部类,和访问普通成员内部类没有任何区别
  • 在 外部类的外部 访问静态内部类,由于静态内部类,不依赖于外部类对象 : new 外部类类名.内部类类名()

3. 例子:

public class OuterClass {
    private static String outerName;
    public  int age;

    static class InnerClass1{
        /* 在静态内部类中可以存在静态成员 */
        public static String _innerName = "static variable";
        public void display(){
            /*
             * 静态内部类只能访问外部类的静态成员变量和方法
             * 不能访问外部类的非静态成员变量和方法
             */
            System.out.println("OutClass name :" + outerName);
        }
    }
    class InnerClass2{
        /* 非静态内部类中不能存在静态成员 */
        public String _innerName = "no static variable";
        /* 非静态内部类中可以调用外部类的任何成员,不管是静态的还是非静态的 */
        public void display(){
            System.out.println("OuterClass name:" + outerName);
            System.out.println("OuterClass age:" + age);
        }
    }
    public void display(){
        /* 外部类能直接访问静态内部类静态元素 */
        System.out.println(InnerClass1._innerName);
        /* 静态内部类可以直接创建实例不需要依赖于外部类 */
        new InnerClass1().display();
        /* 非静态内部的创建需要依赖于外部类 */
        OuterClass.InnerClass2 inner2 = new OuterClass().new InnerClass2();
        /* 非静态内部类的成员需要使用非静态内部类的实例访问 */
        System.out.println(inner2._innerName);
        inner2.display();
    }

    public static void main(String[] args) {
        OuterClass outer = new OuterClass();
        outer.display();
    }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值