【JavaSE系列】第七话 —— 类和对象(2)

☕导航小助手☕

  🍚七、封装

              🍔🍔7.1 封装的概念

              🧀🧀7.2 访问修饰限定符

  🧇八、static成员

              🥩🥩8.1 再谈Student类

              🥡🥡8.2 static修饰成员变量

              🍛🍛8.3 static修饰成员方法

              🍝🍝8.4 static还需要注意的地方

                       🥗注意一:

                       🥙注意二:

              🦪🦪8.5 static成员变量初始化

                        🥣🥣🥣8.5.1 就地初始化

                        🍣🍣🍣8.5.2 静态代码块初始化

  🍱九、代码块

              🍰🍰9.1 代码块概念 以及分类

              🍞🍞9.2 普通代码块

              🥨🥨9.3  构造代码块

              🍲🍲9.4 静态代码块

  🍜十、内部类

              🍤🍤10.1 实例内部类

                        🍗🍗🍗10.1.1 什么是 实例内部类

                        🥐🥐🥐10.1.2 如何去实例化内部类对象

                        🍩🍩🍩10.1.3 实例内部类当中 不能定义 静态的成员变量

                        🥮🥮🥮10.1.4 实例内部类当中,成员变量和外部类成员变量重名

                        🥘🥘🥘10.1.5 实例内部类 所演示的代码

              🎂🎂10.2 静态内部类

                        🍨🍨🍨10.2.1 什么是 静态内部类

                        🍖🍖🍖10.2.2 如何实例化静态内部类

                        🍎🍎🍎10.2.3 如何去访问静态内部类

                        🍓🍓​​​​​​​🍓10.2.4  静态内部类 所演示的代码

              🍉​​​​​​​🍉10.3 匿名内部类

  ​​​​​​​🍅总结


这篇博客承接于上一篇博客: 

【JavaSE系列】第七话 —— 类和对象(1)_哎呀是小张啊的博客-CSDN博客

七、封装

7.1 封装的概念

       面向对象程序 三大特性(注意 是三大特性,而不是三个特性,可能还有第四个,第五个,......,第n个特性):封装、继承、多态;

       而 类和对象阶段,主要研究的就是 封装 特性;

       那么什么是封装呢?简单来说就是 套壳屏蔽细节。

       举个小例子来说明一下 到底什么是封装:

       比如:对于电脑这样一个复杂的设备,提供给用户的就只是:开关机、通过键盘输入,显示器,USB插孔等等,让用户来和计算机进行交互,完成日常事务;

       但实际上,电脑正真工作的却是CPU、显卡、内存等一些硬性原件;

       对于计算机使用者而言,不用关心 内部核心部件,比如主线板上线路是如何布局的,CPU内部是如何设计的等等,他们只需要知道,怎么去开关机、怎么通过键盘和鼠标 与计算机进行交互即可;

       因此 计算机厂商在出厂时,在外部套上壳子,将内部实现细节隐藏起来,仅仅对外提供开关机、鼠标以及键盘、插孔等等,让用户可以与计算机进行交互即可。

              
       封装:将数据和操作数据的方法进行有机结合,隐藏 对象的属性和实现细节,仅对外公开接口来和对象进行 交互。

7.2 访问修饰限定符

       那么,应该怎么样对 数据以及操作数据的方法 来进行封装呢?

       这就涉及到了四个访问修饰限定符:public、private、protected、default 。

       这个知识点博主把单独分享了出来,

       大家感兴趣的话,可以点击下面的传送:

传送门正在建造中......

建造进度(100%)......

🚪传送门:访问修饰限定符🚪


八、static成员

8.1 再谈Student类

       首先创建对象student1、student2,并且每个对象都有各自的 name、age、score等信息,来对不同的对象进行描述的:

public class Student {

    //......

    public String name;
    public int age;
    public double score;
    public String classes;

    //......

    public static void main(String[] args) {
        Student student1 = new Student("bit",18,100);
        Student student2 = new Student("张三",19,100);
}

       那么,通过打断点的形式,我们可以知道 每个对象所存储的数据:

       假设三个同学是同一个班的,即:在同一间教室上课,那么有没有一种办法,可以同时来保存他们在同一间教室上课这个信息呢......

       在Student类中定义的成员变量,每个对象中都会包含一份,应为需要使用这些信息来描述具体的学生;

       而现在要表示学生上课的教室,这个教室的属性 并不需要每个学生对象中都存储一份,而是让每一位学生所共享的;

       在Java中,被static修饰的成员,称之为 静态成员(类成员),其不属于某一个具体的对象,而是所有的对象所共享的。

8.2 static修饰成员变量

       static修饰的成员变量,称为 静态成员变量;

       静态成员变量 的最大特性:不属于某个具体的对象,是所有对象所共享的。

       所以,如果我们想要访问该静态成员变量的话,不需要new一个对象,

可以直接用 类名.静态成员变量 来进行访问:

       上面的整体代码是这个样子的:

class Student{
    public String name;
    public int age;
    public double score;
    public static String classes;

    public Student(String name, int age, double score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                ", 班级=" + classes +
                '}';
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Student student1 = new Student("bit",18,90);
        Student student2 = new Student("张三",20,100);
        Student.classes = "Java";
        System.out.println(student1);
        System.out.println(student2);
    }
}

       静态成员变量 不建议 通过 对象名.静态成员变量 来进行访问(这样写是合法不合理的):

【静态成员变量的静态属性】

  1. 不属于某个具体的对象,是类的属性,所有对象所共享的,不存储在某个对象的空间中;
  2. 即可以通过对象访问,也可以通过类名访问,不过一般更加推荐使用类名访问(通过对象访问 就像是那个 合法但是不合理);
  3. 静态成员变量(类变量) 存储在方法区中;
  4. 生命周期伴随类的一生(即:随类的创建而创建,随类的销毁而销毁)。

8.3 static修饰成员方法

       一般类中的数据成员 都设置为private,而成员方法设置为public;

那设置之后,Student类中的classes属性 如何在类外访问呢?

       那static属性应该如何去访问呢?

       Java中,被static修饰的成员方法 称为 静态成员方法,是类的方法,不是某个对象所特有的;

       此时,我们可以用 类名.classes来进行访问:

       这个是完整的代码示例:

class Student{

    public String name;
    public int age;
    public double score;
    public static String classes;


    public Student(String name, int age, double score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                ", 班级=" + classes +
                '}';
    }

   public static void func(){
        System.out.println("这个是一个静态的成员方法!!!!!!");
    }
}

public class TestDemo {
    public static void main(String[] args) {
        Student.func();
    }
}

【静态方法特性】

  1. 不属于某个具体的对象,是类方法;
  2. 可以通过对象调用,也可以通过 类名.静态方法名(......) 方式调用,当然,也还是更推荐使用 类名.静态方法名(......) 来调用,通过对象调用 就是“合法但是不合理”;
  3. 静态方法 没有隐藏的this引用参数,因此不能在静态方法中 访问任何非静态成员变量;
  4. 静态方法中不能调用 任何非静态方法,因为非静态方法有this参数,在静态方法中 调用时无法传递this引用。

8.4 static还需要注意的地方

注意一:

class Student{
    public String name;
    public int age;
    public double score;
    public static String classes;

    public static void func(){
        System.out.println("这个是一个静态的成员方法!!!!!!");
    }
}

public class TestDemo {
    public static void main(String[] args) {
        Student student1 = null;
        student1.classes = "Java";
        System.out.println(student1.classes);
    }
}

       如果没有看编译结果的话,很多人的第一反应是:会发生空指针异常;

但是,正确的编译结果是:

 其实原因是这样的:

       在实际生活中,我们也不会这样去访问的(这样是合法不合理的),乖乖的用类名去访问就可以了。 

【总结】静态的成员变量 和 静态的成员方法,都不依赖于对象;因为他们是类变量。

注意二:

       在普通的方法里面 加上 静态成员变量(或成员方法,这里只列了成员变量的例子),观察是否可以访问:

这个可以访问的原因:

       要调用doClass()方法的前提是:先前需要实例化出一个对象student;

       所以可以调用。

      在静态的成员方法 里面加上 普通的成员变量(或成员方法,这里只列了成员变量的例子),观察是否可以访问:

//注意二所使用的代码:

class Student{
    public String name;
    public int age;
    public double score;
    public static String classes;

    public Student(String name) {
        this.name = name;
    }

    public static void func(){
        //System.out.println("这个是一个静态的成员方法!!!!!!" + name);
    }
    public void doClass(){
        System.out.println(this.name + "正在上课!"+" 班级:"+classes);
    }
}

public class TestDemo {
    public static void main(String[] args) {
        Student.classes = "Java";
        Student student = new Student("张三");
        student.doClass();
    }
}

原因很简单:

       在调用 func()方法的时候,没有实例化出一个对象(对于name这些普通成员变量来说,一定是要依赖于对象的,即:想要访问name,必须要有一个对象) 。


弯弯绕绕:static -> 静态的 -> 类方法、类变量 -> 类看成是一个模板,只有一份 -> 单身狗 -> 没对象 -> 没对象的话,小钱钱就可以自己留着,不给对象使用,也就不依赖于对象了。

【总结】静态的不依赖于对象,非静态的依赖于对象。

       所以,有static的必须要用new一个对象,才可以去调用那些非静态的成员变量和成员方法;这就解释了为什么一开始在 写函数的时候,是要求这样写的(需要写上 static):

否则的话,在一开始接触到这个的时候,肯定是脑袋一片空白~ 

8.5 static成员变量初始化

【注意】静态成员变量 一般不会放在构造方法中来初始化,构造方法中初始化的是 与对象相关的实例属性;

静态成员变量的初始化分为两种:就地初始化 和 静态代码块初始化。

8.5.1 就地初始化

       就地初始化 指的是:在定义时直接给出初始值:

class Student{
    public String name;
    public int age;
    public double score;

    public static String classes = "Java";

    //......
}

8.5.2 静态代码块初始化

       在学习这一部分内容的时候,还是需要来介绍一下什么是代码块......


九、代码块

9.1 代码块概念 以及分类

       使用 {} 定义的一段代码称为代码块。

根据代码块定义的位置 以及关键字,又可分为以下四类:

  1. 实例代码块 / 构造代码块
  2. 静态代码块;
  3. 本地代码块 / 普通代码块(用不到);
  4. 同步代码块(目前用不到)。

9.2 普通代码块

       普通代码块:定义在方法中的代码块:

9.3  构造代码块

        构造代码块:定义在类中的代码块(不加修饰符),也叫:实例代码块。

class Student2 {
    public String name;
    public int age;
    public double score;

    public Student2(String name, int age, double score) {
        this.name = name;
        this.age = age;
        this.score = score;
        System.out.println("调用带有3个参数的构造方法!");
    }

    {
        System.out.println("实例代码块!!!!!!");
    }

    public static void main(String[] args) {
        Student2 student = new Student2("张三",19,100);
    }
}

9.4 静态代码块

       使用static定义的代码块 称为静态代码块;

       一般用于初始化静态成员变量。

 

【注意】如果有多个静态代码块,那么执行的顺序和定义的顺序有关;定义在后面的 静态代码块 会把 定义在前面的 给覆盖掉(当然,只是赋值覆盖,就相当于把两个 静态代码块连起来,然后去覆盖,像打印的就不会覆盖了):

class Student2 {
    public String name;
    public int age;
    public double score;
    public static String classes;

    public Student2(String name, int age, double score) {
        this.name = name;
        this.age = age;
        this.score = score;
        System.out.println("调用带有3个参数的构造方法!");
    }

    @Override
    public String toString() {
        return "Student2{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                ",班级= " + classes +
                '}';
    }

    {
        System.out.println("实例代码块!!!!!!");
    }

    static {
        classes = "Java_1";
        System.out.println("静态代码块!!!!!!");
    }
    static {
        classes = "Java_2";
        System.out.println("静态代码块!!!!!!");
    }
    public static void main(String[] args) {
        Student2 student = new Student2("张三",19,100);
        System.out.println(student);

        System.out.println("============================================");

        Student2 student2 = new Student2("李四",19,100);
        System.out.println(student2);
    }
}

 


十、内部类

       内部类也是一种类,其重点在于内部二字;

       在一个类的内部 定义的类,叫做 内部类。

内部类 可以分为以下几种:

  1. 实例内部类;
  2. 静态内部类;
  3. 匿名内部类。

       所以说,以后 如果说内部类的时候,需要带上前缀(不同的内部类,性质、使用方式等等都是有区别的)。

10.1 实例内部类

10.1.1 什么是 实例内部类

class OuterClass {

    //普通成员变量(实例成员变量)
    public int data1 = 10;
    private int data2 = 20;
    public static int data3 = 30;


    class InnerClass {

        //class InterClass 这个类就叫做 实例内部类

    }

}

10.1.2 如何去实例化内部类对象

//外部类名.内部类名 变量 = 外部类对象的引用.new 内部类名();

10.1.3 实例内部类当中 不能定义 静态的成员变量

原因:内部类InnerClass需要 外部类对象 才能够进行实例化的,如果里面有 静态static,那么data6就不需要外部类对象。

       当然,也不可以含有静态方法,大家可以自己去试一试:

       如果要定义,必须是 编译的时候就要确定的值(即:必须是 static finna的)(内部类里面内部类里面内部类里面):

       如果实在内部类外面定义,那就肯定是编译错误:

10.1.4 实例内部类当中,成员变量和外部类成员变量重名

       那么,就会优先使用 内部类(自己)的:

       那么,如何去调用 外部类的data1呢?

10.1.5 实例内部类 所演示的代码

class OuterClass {
    //普通成员变量(实例成员变量)
    public int data1 = 10;
    private int data2 = 20;
    public static int data3 = 30;

    /**
     * 实例内部类
     */
    class InnerClass {
        public int data1 = 1000;
        public int data4 = 40;
        public int data5 = 50;
        public static final int data6 = 60;//常量-》编译的时候,就已经确定这个值是几了

        //内部类里面不可以有静态方法
//        public static void funcStatic(){
//
//        }
        public InnerClass(){
            System.out.println("InnerClass的构造方法!!!!!!");
        }
        public void method(){
            System.out.println("Java:"+OuterClass.this.data1);
            System.out.println(data2);
            System.out.println(data3);
            System.out.println(data4);
            System.out.println(data5);
            System.out.println(data6);
            System.out.println("InnerClass的一个method方法!!!!!!");
        }


    }
    public void methodOut(){
        //static final int c = 10;
    }
}
public class TestDemo {
    public static void main(String[] args) {
        OuterClass outerClass = new OuterClass();
        OuterClass.InnerClass innerClass = outerClass.new InnerClass();
        innerClass.method();
    }
    public static void main1(String[] args) {
        OuterClass outerClass = new OuterClass();
        System.out.println(outerClass.data1);

        //外部类名.内部类名 变量 = 外部类对象的引用.new 内部类名();
        OuterClass.InnerClass innerClass = outerClass.new InnerClass();
        OuterClass.InnerClass innerClass1 = new OuterClass().new InnerClass();

        //new OuterClass():匿名对象:一般在使用1次的时候(每一次使用都要new一个对象)
//        System.out.println(new OuterClass().data1);
//        System.out.println(new OuterClass().data2);
    }


}

10.2 静态内部类

10.2.1 什么是 静态内部类

       被static修饰的内部类叫做 静态内部类。

class OuterClass2 {
    public int data1 = 10;
    private int data2 = 20;
    public static int data3 = 30;


    static class InnerClass {

        //这个类就叫做静态内部类

    }
}

10.2.2 如何实例化静态内部类

//外部类名.静态内部类名 变量 = new 外部类名.静态内部类名

 

10.2.3 如何去访问静态内部类

       在静态内部类当中,只能访问外部类的静态的成员:

       如果要访问外部类的非静态成员,那么高怎么去访问呢?

       ——去提供外部类对象:

       去访问方法的时候也是一样的,这里就不演示了。 

10.2.4  静态内部类 所演示的代码

class OuterClass2 {
    public int data1 = 10;
    public int data2 = 20;
    public static int data3 = 30;

    public void method() {
        System.out.println("OuterClass2::method()");
    }
    static class InnerClass {
        //这个类就叫做静态内部类

        public int data4 = 40;
        private int data5 = 50;
        public static int data6 = 60;
        OuterClass outerClass = new OuterClass();

        public InnerClass() {
            System.out.println("InnerClass的构造方法!!!!!!");
        }

        public void method() {
            System.out.println(outerClass.data1);
            System.out.println(outerClass.data2);
            System.out.println(data3);
            System.out.println(data4);
            System.out.println(data5);
            System.out.println(data6);
            System.out.println("innerclass的method的方法!!!!!!");
        }
    }
}

public class TestDemo2 {
    public static void main(String[] args) {
        //调用的时候不需要外部类对象,所以 静态内部类使用的频率会比较多一点
        OuterClass2.InnerClass innerClass = new OuterClass2.InnerClass();
    }
}

10.3 匿名内部类

       这部分内容等到后面 接口 的内容再详细介绍嗷......

传送门正在建造中......

建造进度(0%)......


总结

花费了好几天的时间总结了关于 类与对象 的知识 到此就结束了;

当然,还有一些不足的地方;

后期也要修修改改;

希望大家收获满满呀!!!!!!

如果铁铁们可以一键三连那就更棒了,特别特别感谢 ୧(๑•̀⌄•́๑)૭ 。

  • 93
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 91
    评论
评论 91
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

哎呀是小张啊

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值