【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内部是如何设计的等等,他们只需要知道,怎么去开关机、怎么通过键盘和鼠标 与计算机进行交互即可;

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

【JavaSE系列】第七话 —— 类和对象(2)_第1张图片               【JavaSE系列】第七话 —— 类和对象(2)_第2张图片
       封装:将数据和操作数据的方法进行有机结合,隐藏 对象的属性和实现细节,仅对外公开接口来和对象进行 交互。

7.2 访问修饰限定符

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

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

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

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

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

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

传送门:访问修饰限定符


八、static成员

【JavaSE系列】第七话 —— 类和对象(2)_第3张图片

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);
    }
}

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

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

【JavaSE系列】第七话 —— 类和对象(2)_第4张图片

 其实原因是这样的:

【JavaSE系列】第七话 —— 类和对象(2)_第5张图片

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

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

注意二:

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

这个可以访问的原因:

       要调用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的必须要用new一个对象,这就解释了为什么一开始在写主函数的时候,是要这样写的:

【JavaSE系列】第七话 —— 类和对象(2)_第6张图片

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 内部类名();

【JavaSE系列】第七话 —— 类和对象(2)_第7张图片

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

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

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

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

【JavaSE系列】第七话 —— 类和对象(2)_第8张图片

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

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 外部类名.静态内部类名

 【JavaSE系列】第七话 —— 类和对象(2)_第9张图片

10.2.3 如何去访问静态内部类

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

【JavaSE系列】第七话 —— 类和对象(2)_第10张图片

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

       ——去提供外部类对象:

【JavaSE系列】第七话 —— 类和对象(2)_第11张图片

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

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%)......


总结

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

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

后期也要修修改改;

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

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

你可能感兴趣的:(JavaSE系列,java,JavaSE,开发语言,后端)