【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 就地初始化

九、代码块

9.1 代码块概念 以及分类

9.2 普通代码块

9.3  构造代码块

9.4 静态代码块

十、内部类

10.1 实例内部类

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

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

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

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

 10.2 静态内部类

10.2.2 如何实例化静态内部类 

 10.2.3 如何去访问静态内部类

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

10.3 匿名内部类

总结



前言

本节内容接上一小节内容,继续讲解关于Java的类和对象的有关内容。让我们继续学习本节内容,更好的了解Java的核心吧!!!

七、封装

7.1 封装的概念

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

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

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

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

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

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

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

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

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

 7.2 访问修饰限定符

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

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

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

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

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

八、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;所以可以调用。


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

原因很简单:

在调用 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  构造代码块

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

 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 实例内部类

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

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

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

总结

  • 14
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值