> 文档中心 > 【JavaSE系列】第七话 —— 类和对象(2)

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

这篇博客承接于上一篇博客:【JavaSE系列】第七话 —— 类和对象(1)

🚗目录🚗

   🚓七、封装

         🚕🚕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 匿名内部类

 🌁总结


七、封装

7.1 封装的概念

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

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

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

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

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

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

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

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

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

7.2 访问修饰限定符

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

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

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

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

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

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


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

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


总结

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

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

后期也要修修改改;

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

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

笑话娱乐网站