Java SE 内部类简单讲解,数据结构会详细讲解(链表)

1.内部类概念

1.内部的完整结构又只为外部事物提供服务,那么这个内部完整结构最好使用内部类。

在java中可以将一个类在另一个或者一个方法内部,前者称为内部类后者称为外部类。

2.我现在有一个类,要描述一个对象,但是这个对象是由多个对象组成的,如火车,火车是由若干一样的车厢组成,我要想组成火车就需要多个车厢,而这个车厢就可以理解为内部类。

有点像组合

3.内部类分为

静态内部类

实例内部类

匿名内部类

局部内部类

2.内部类代码实现

1.新建一个包名字为demoinnerclass

2.定义一个类是Outer

package demoinnerclass;
class Outer{}//外部类

public class Test {
}

2.1静态内部类

1.在类中又定义了一个由static修饰的内部类叫做静态内部类(静态内部类用的最多)

代码

package demoinnerclass;
class Outer{
    public int date1 = 1;
    private int date2 = 2;
    public static int date3 = 3 ;
    static class interClass{
        //静态内部类
    }
}

public class Test {
}

2. 我们可以看到我们使用不了date1和date2,但是能够使用date3,date4,date5,date6

3.注意要点

(1)在静态内部类中是否能够直接访问外部类对象的非静态成员变量呢?

答案:不可以直接访问(注意是不能直接访问)

解析:因为外部类对象的成员依赖外部类对象

(2)如何在静态内部类访问外部类中的对象呢?

答案:通过在静态内部类中初始化外部类对象,再通过初始化的对象对外部类中的成员变量进行引用

(4)被stattic修饰的在外部类中可以被静态内部类中可以访问

(3)如何使用静态内部类(在代码注释部分以详细讲解)

代码

package demoinnerclass;
class Outer{
    public int date1 = 1;
    private int date2 = 2;
    public static int date3 = 3 ;
    static class interClass{
        //静态内部类
        public int date4 = 4;
        public int date5 = 5;
        public static int date6 = 6;
        //也可以由构造方法
        public void test(){
            System.out.println("InnerClass::test()");
            Outer outer = new Outer();
            System.out.println(outer.date1);
            System.out.println(outer.date2);
            System.out.println(date3);
            System.out.println(date4);
            System.out.println(date5);
            System.out.println(date6);
        }
    }
    public  void  testFunc(){
        System.out.println("Outer::testFunc()");
    }

}

public class Test {
    public static void main(String[] args) {
        //如何获得静态内部类这个对象
        //由于里面有一个静态内部类所以我们不能够初始化对象
        //可以把静态内部类当作一个静态的成员可以通过调用的方式使用
        Outer.interClass inn = new Outer.interClass();//格式//你看我是没有new这个对象的而是通过调用的方式
        inn.test();//通过inn调用静态内部类中的test方法

    }

}

(5)静态内部类也会生成字节码文件,组合方式是,外部类名$内部类类名class

3.实例内部类

1.1实例内部类概念

在外部类里再定义一个类,这个类没有被任何关键字修饰,那么这个类就是局部内部类

2.2实例内部类实现

代码

package demoinnerclass;
class OuterClass{
    public int date1 = 1;
    private int date2 = 2 ;
    public static int data3 = 3;

    class  InnerClass{//实例内部类
        public  int date4 = 4;
        private int date5 = 5;
        //常量在编译的时候是确定的
        public  static final int data6 = 6;
        public void test(){
            
        }
    }
}

public class Test {
    public static void main(String[] args) {
//        InnerClass innerClass = new OuterClass();//和静态内部类一样不能够直接调用
    }
}

正确使用局部内部类是这样代码如下:有两种使用方式看你喜欢哪一个

package demoinnerclass;
class OuterClass{
    public int date1 = 1;
    private int date2 = 2 ;
    public static int data3 = 3;

    class  InnerClass{//实例内部类
        public  int date4 = 4;
        private int date5 = 5;
        //常量在编译的时候是确定的
        public  static final int data6 = 6;
        public void test(){

        }
    }
}

public class Test {
    public static void main(String[] args) {
//        InnerClass innerClass = new OuterClass();//和静态内部类一样不能够直接调用
        
        
        OuterClass out = new OuterClass();//第一种
        OuterClass.InnerClass innerClass = out.new InnerClass();
        
        
        
        OuterClass.InnerClass innerClass2 = new OuterClass().new InnerClass();//第二种
    }
}

 3.3使用局部内部类

代码

我们用了第一种方法来使用局部内部类,再通过调用innerClass中调用test方法,最后运行程序结果是:“实例内部类”

class OuterClass {
    public int date1 = 1;
    private int date2 = 2;
    public static int data3 = 3;

    class InnerClass {//实例内部类
        public int date4 = 4;
        private int date5 = 5;
        //常量在编译的时候是确定的
        public static final int data6 = 6;

        public void test() {
            System.out.println("实例内部类");
        }
    }
}

class Frank {
    static class OuterClass {
        public int date1 = 1;
        private int date2 = 2;
        public static final int data3 = 3;

        class InnerClass {//实例内部类
            public int date4 = 4;
            private int date5 = 5;
            //常量在编译的时候是确定的
            public static final int data6 = 6;

            public void test() {
                System.out.println("实例内部类");
            }
        }
    }

    public static class Test {
        public static void main(String[] args) {
            OuterClass out = new OuterClass(); // 第一种
            OuterClass.InnerClass innerClass = out.new InnerClass();
            innerClass.test();
        }
    }
}

(1)所以可以看出静态内部类是比较好的相较于实例内部类,我不用再 实例化一次对象相较于局部内类,再静态内部类中我们是直接调用了InnerClass,而局部内部类却是new InnerClass。

(2)如果要定义static成员,我们记得要用final修饰。(将它变成一个常量)

(3)实例内部类中不能定义静态成员变量(包括静态常量)

(4)在运行的过程中优先访问内部类中的同名成员,如果我们想访问外部类,有两种方式,

第一种

实例化外部类对象,然后通过外部类对象访问这个同名成员变量

第二种

外部类类名+.this+.同名成员变量(同名的是date1)

System.out.println(OuterClass.this.date1);

可以理解为实例内部类中包含两个this,一个是外部类的this一个是实例内部类自己的this。(特殊记一下)

最终代码

class OuterClass {
    public int date1 = 1;
    private int date2 = 2;
    public static final int data3 = 3;
    public static final int data6 = 6;

    //实例内部类
    class InnerClass {
        public int date4 = 4;
        private int date5 = 5;

        public void test() {
            System.out.println("date1" + date1);
            System.out.println("data2" + date2);
            System.out.println("data3" + data3);
            System.out.println("data4" + date4);
            System.out.println("data5" + date5);
            System.out.println("data6" + data6);
        }
    }
}

public class Frank {
    public static void main(String[] args) {
        OuterClass out = new OuterClass();
        OuterClass.InnerClass innerClass = out.new InnerClass();
        innerClass.test();
    }
}

4.匿名内部类 

4.1匿名对象

1.如果我们只使用一次这个对象那么我们就使用匿名对象。

代码如下

class Test{
    public  void func(){
        System.out.println("func()");

    };
}


public class Frank {
    public static void main(String[] args) {
        Test test =  new Test();
        test.func();
        //只实例化了一个test对象
        test.func();
        System.out.println("//");
        new Test().func();//匿名对象
        // 实例化了两个test对象
        new Test().func();//匿名对象
    }
}

4.2匿名内部类 

1.代码

interface InterfaceA{
    void func();
}
 class TestA implements InterfaceA{

     @Override
     public void func() {
         System.out.println("我是重写的func方法");
     }
 }


class Test{
    public  void func(){
        System.out.println("func()");

    };
}


public class Frank {
    public static void main(String[] args) {
        Test test =  new Test();
        System.out.println("///");
       InterfaceA a =  new InterfaceA(){
            @Override
            public void func() {
                System.out.println("哈哈,不懂了吧");
            }
        };
    }
}

画红圈的就是匿名内部类。 

2.可以理解为画红圈的部分是一个类实现了一个接口,并且重写了接口当中的

func()方法。

  接口引用了一个对象。然后访问func()方法。

5.局部内部类(比较鸡肋)

5.1.概念

1.在一个类中的方法中定义一个类

2.只能在方法当中对这个类进行实例化(只能在方法内使用)

5.2注意事项

1.会生成字节码文件

2.不能被public  static private 等修饰符修饰。

3.几乎不用!!!!!!!!!!!!!!!!几乎不用啊啊啊啊啊!!!!!!!

6.用的最多的是静态内部类和匿名内部类

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Frank1-0-2-4

我会继续努力的,十分感谢谢谢你

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值