Java内部类(成员内部类、静态内部类、方法内部类、匿名内部类)

        

        成为一名合格的工程师需要一年到三年,现在遇到困难的,觉得不会的不要慌,学习是积累的,有一定步骤的。

内部类

内部类的定义

将一个类定义在另一个给类里面或者方法里面,这样的类就被称为内部类。
内部类可以分为四种:成员内部类、局部内部类、匿名内部类、静态内部类,下面我们逐一介绍这四种内部类。

一.成员内部类

他定义在另一个类中。一般定义格式如下

Inner类定义在Outer类的内部,相当于Outer类的成员变量的位置

class C{
    class D{

    }
}

因为类C相对与类D在外面,我们且称类C为外部类。

1.成员内部类内部不允许存在任何static变量或方法(可以用public static final来定义常量),但是可以访问外部类的实例变量、静态变量、实例方法、静态方法。 

 (静态变量和静态方法都不能这么申明)

2.成员内部类可以无条件访问外部类的属性和方法,但是外部类想要访问内部类属性或方法时,必须要创建一个内部类对象,然后通过该对象访问内部类的属性或方法

3.成员内部类无条件访问外部类的属性和方法(Inner类可以使用任意访问修饰符,如:public、private、protected等。)

class C{
    private String name = "外部类";
    public void run(){
        System.out.println("外部类奔跑");
    }
    class D{
        public void say(){
            System.out.println(name);
            run();
        }
    }
}

外部类访问内部类属性和方法

class C{
    private String name = "外部类";
    public void run(){
        System.out.println("外部类奔跑");
    }
    /*使用内部类的属性和方法*/
    public void eat(){
        D d = new D();
        System.out.println(d.value);
        d.say();
    }
    class D{
        private String value = "DDD";
        public void say(){
            System.out.println(name);
            run();
        }
    }
}

外部类属性或方法隐藏

如果外部类和内部类具有相同的成员变量或方法,内部类可以直接访问内部类的成员变量或方法,但如果内部类访问外部类的成员变量或者方法时,需要使用this关键字

外部类类名.this.属性/方法。

class C{
    private String name = "外部类";
    public void run(){
        System.out.println("外部类奔跑");
    }
    /*使用内部类的属性和方法*/
    public void eat(){
        D d = new D();
        System.out.println(d.value);
        d.say();
    }
    class D{
        private String value = "DDD";
        private String name = "内部类";
        public void say(){
            System.out.println(C.this.name);
            System.out.println(name);
            run();
        }
    }
}

创建内部类对象

显然成员内部类是寄生于外部类,创建内部类对象就必须先创造外部类对象。

在其他类中,是看不见一个类的内部类的。只能通过先创建外部类对象:Outer o = new outer();再 创建内部类:Inner i = o.new Inner()。

在自己本外部类中:1.静态方法内也需要通过上述创建内部类

                                2.实例方法内可以按普通类创建对象


public class Test10 {
    public static void main(String[] args) {
        /*方式1创建成员内部类对象*/
        C c = new C();
        C.D d = c.new D();
        /*方式2创建成员内部类对象*/
        C.D d1 = c.getClassD();
    }
}
class C{
    private String name = "外部类";
    public void run(){
        System.out.println("外部类奔跑");
    }
    /*创建一个返回D对象的方法*/
    public D getClassD(){
        return new D();
    }
    /*使用内部类的属性和方法*/
    public void eat(){
        D d = new D();
        System.out.println(d.value);
        d.say();
    }
    class D{
        private String value = "DDD";
        private String name = "内部类";
        public void say(){
            System.out.println(C.this.name);
            System.out.println(name);
            run();
        }
    }
}

二.静态内部类

静态内部类和成员内部类相比多了一个static修饰符。它与类的静态成员变量一般,是不依赖于外部类的。

        1.静态内部类创建对象不需要依赖外部类对象可以直接创建。(但是需要外部类来定位)

        在自己本外部类中:无论是静态方法还是实例方法,都可以直接创建。

        在其他的类中:使用内部类的时候仍然使用外部类,定位内部类。见Test方法。
        2.静态内部类不可以使用任何外部类的非static属性,也不能访问非static方法(非static方法可以通过创建外部类对象来访问),但可以存在自己的成员变量、实例方法。

class Outer {
    public String name = "test";
    private static int age =20;

    static class Inner{
        private String name;
        public void fun()
        {
            System.out.println(name);
            System.out.println(age);
        }
    }
}
public class Test{
    public static void main(String [] args)
    {
        Outer.Inner in = new Outer.Inner();
    }
}

三.方法内部类


方法内部类顾名思义就是定义在方法里的类
        1.方法内部类不允许使用访问权限修饰符(public、private、protected)均不允许。内部类也不能使用 static 修饰符(方法里面只有局部变量)。

class Outer{
    private int num =5;
    public void dispaly(final int temp)
    {
        //方法内部类即嵌套在方法里面
        public class Inner{
        }
    }
}
public class Test{
    public static void main(String[] args)
    {}
}

在这里插入图片描述

        2. 方法内部类对外部完全隐藏,除了创建这个类的方法可以访问它以外,其他地方均不能访问 (换句话说其他方法或者类都不知道有这个类的存在)方法内部类对外部完全隐藏,除了创建这个类的方法可以访问它,其他地方均不能访问。


        3. 方法内部类如果想要使用方法形参,该形参必须使用final声明(JDK8形参变为隐式final声明)

class Outer{
    private int num =5;
    //普通方法
    public void dispaly(int temp)
    {
        //方法内部类即嵌套在方法里面
        class Inner{
            public void fun()
            {
                System.out.println(num);
                temp++;
                System.out.println(temp);
            }
        }
        //方法内部类在方法里面创建
        new Inner().fun();
    }
}
public class Test{
    public static void main(String[] args)
    {
        Outer out = new Outer();
        out.dispaly(2);
    }
}

在这里插入图片描述

四.匿名内部类


  匿名内部类就是一个没有名字的方法内部类,因此特点和方法与方法内部类完全一致,除此之外,还有自己的特点:
1.匿名内部类必须继承一个抽象类或者实现一个接口。
2.匿名内部类没有类名,因此没有构造方法。

匿名内部类没有构造方法。也是唯一没有构造方法的内部类。匿名内部类和局部内部类只能访问外部类的final变量。

//匿名内部类
//声明一个接口
interface MyInterface {
    //接口中方法没有方法体
    void test();
}
class Outer{
    private int num = 5;
    public void dispaly(int temp)
    {
        //匿名内部类,匿名的实现了MyInterface接口
        //隐藏的class声明
        new MyInterface()
        {
            public void test()
            {
                System.out.println("匿名实现MyInterface接口");
                System.out.println(temp);
            }
        }.test();
    }
}
public class Test{
    public static void main(String[] args)
    {
        Outer out = new Outer();
        out.dispaly(3);
    }
}
public class Test13 {
    public static void main(String[] args) {
        driveCar(new Car(){
            @Override
            public void drive() {
                System.out.println("驾驶着BMW汽车");
            }
        });
    }
    public static void driveCar(Car car){
        car.drive();
    }
}

interface Car {
    void drive();
}

五. 内部类与外部类的关系


        对于非静态的内部类,内部类的创建依赖外部类的实例对象,在没有外部类实例之前是无法创建内部类的。
        内部类可以直接访问外部类的元素(包括私有域)—外部类在内部类之前创建,创建内部类时会将外部类的对象传入

class Outer{
    //成员变量  与对象有关
    private String msg;
    private int age;
    //--------------------------
    class Inner{
        public void dispaly()
        {
            //此处有一个隐藏的Outer.this
            msg = "test";
            age = 20;
            System.out.println(msg);
            System.out.println(age);
        }
    }
    //--------------------------
    public void test()
    {
        Inner in = new Inner();
        in.dispaly();
    }
}
public class Test{
    public static void main(String[] args)
    {
        Outer out = new Outer();
        out.test();
    }
}


        外部类可以通过内部类的引用间接访问内部类元素 – -要想访问内部类属性,必须先创建内部类对象。但是其实不光外部类,其他的类也可以通过此方法访问到内部类属性(内部类是一个相对独立的个体,与外部类没有关系)。

class Outer{
    public void dispaly()
    {
        //外部类通过创建内部类的对象间接访问内部类元素
        Inner in = new Inner();
        in.dispaly();
    }
    class Inner{
        public void dispaly()
        {
            System.out.println("内部类");
        }
    }
}
public class Test1{
    public static void main(String[] args)
    {
        Outer out = new Outer();
        out.dispaly();
    }
}


六.成员内部类和静态内部类

1.成员内部类可以访问外部类的所有属性和方法。成员内部类不能存在任何static修饰的属性或者方法。

2.静态内部类不能访问外部类非static修饰的属性和方法,但是可以通过创建外部类对象的方式来访问外部类实例方法(这种方法和其他类来创建对象访问外部类没有差别)。静态内部类里面可以存在自己的成员变量、实例方法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值