【JavaSE】-- 类和对象(2)

news2024/11/17 10:52:50

文章目录

  • 6. 封装
    • 6.1 封装的概念
    • 6.2 访问限定符
    • 6.3 封装拓展之包
      • 6.3.1 包的概念
      • 6.3.2 导入包中的类
      • 6.3.3 自定义包
  • 7. static成员
    • 7.1 再谈学生类
    • 7.2 static修饰成员变量
    • 7.3 static修饰成员方法
    • 7.4 static成员变量初始化
  • 8. 代码块
    • 8.1 代码块概念以及分类
    • 8.2 普通代码块
    • 8.3 构造代码块
    • 8.4 静态代码块
  • 10. 对象的打印

6. 封装


6.1 封装的概念

对于面向对象的语言来说 有几个比较重要的特征:封装、继承、多态。
这里有一个误区:这三个特征不是哪个语言的特征,而是面向对象的特征。
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互.

6.2 访问限定符

访问权限用来控制方法或者字段能否直接在类外使用

No范围privatedefaultprotectedpublic
1同一个包的同一类
2同一个包中的不同类
3不同包中的子类
4不同包中的非子类

【说明:】

  • protected主要是用在继承中
  • default权限指:什么都不写时的默认权限
  • 访问权限除了可以限定类中成员的可见性,也可以控制类的可见性。
class Student {
   private String name;
   private int age;
   private String stuNum;


   // get  和  set方法
    //当成员变量被private修饰了之后  该成员变量只能在同一个包中的同一个类中被访问
    // 提供get 和 set方法 供给访问

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getStuNum() {
        return stuNum;
    }

    public void setStuNum(String stuNum) {
        this.stuNum = stuNum;
    }


    //构造方法
    public Student(String name, int age, String stuNum) {
        this.name = name;
        this.age = age;
        this.stuNum = stuNum;
    }
}

public static void main(String[] args) {
    Student student = new Student("zhangsan", 11, "202320044118");
    System.out.println(student.getName());// zhangsan
    // System.out.println(student.name);//报错
}

6.3 封装拓展之包


6.3.1 包的概念

在面向对象体系中,提出了一个软件包的概念,即:为了更好的管理类,把多个类收集在一起成为一组,称为软件包。有点类似于目录。比如:为了更好的管理电脑中的歌曲,一种好的方式就是将相同属性的歌曲放在相同文件下,也可以对某个文件夹下的音乐进行更详细的分类。

包的本质就是一个 文件夹 ,可以理解为包就是为了组织类的; 在同一个工程中允许存在相同名称的类,只要处在不同的包中即可。

6.3.2 导入包中的类

Java 中已经提供了很多现成的类供我们使用. 例如Date类:可以使用 java.util.Date 导入 java.util 这个包中的 Date类.

//导入一个包(方法1)
public static void main(String[] args) {
    java.util.Date date = new java.util.Date();
     // 得到一个毫秒级别的时间戳
    System.out.println(date.getTime());
}

但是这种写法比较麻烦一些, 可以使用 import语句导入包.

import java.util.Date;
// 或者写成
// import java.util.*;
// 但是这种写法并不推荐

public class Test {
    public static void main(String[] args) {
        Date date = new Date();
// 得到一个毫秒级别的时间戳
        System.out.println(date.getTime());
    }
}

更建议显式的指定要导入的类名. 否则还是容易出现冲突的情况.

import java.util.*;
import java.sql.*;
public class Test {
    public static void main(String[] args) {
// util 和 sql 中都存在一个 Date 这样的类, 此时就会出现歧义, 编译出错
        Date date = new Date();
        System.out.println(date.getTime());
    }
}
// 编译出错
Error:(5, 9) java:Date的引用不明确
        java.sql 中的类 java.sql.Date 和 java.util 中的类 java.util.Date 都匹配

在这里插入图片描述

6.3.3 自定义包

鼠标放在src上右键—new—package
在这里插入图片描述

包名采用小驼峰的写法,一般采用公司名的倒写形式(比如:com.baidu.www)

建完包之后 如果包名是一行的话:
在这里插入图片描述
打开文件路径:
在这里插入图片描述
在这里插入图片描述
src: 程序的默认包,程序在运行的时候默认是在Src这个包下面找可执行程序,去执行。

7. static成员


7.1 再谈学生类

public class Student {
    private String name;
    private int age;
    private String stuNum;
    private String classRoom;

    public Student(String name, int age, String stuNum, String classRoom) {
        this.name = name;
        this.age = age;
        this.stuNum = stuNum;
        this.classRoom = classRoom;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getStuNum() {
        return stuNum;
    }

    public void setStuNum(String stuNum) {
        this.stuNum = stuNum;
    }

    public String getClassRoom() {
        return classRoom;
    }

    public void setClassRoom(String classRoom) {
        this.classRoom = classRoom;
    }
}

public class Test {
    public static void main(String[] args) {
        Student student1 =
                new Student("zhansgan", 21, "551453666", "1103");
        Student student2 =
                new Student("lisi", 21, "1576632", "1103");
        Student student3 =
                new Student("wangwu", 21, "588556546565", "1103");

    }
}

实例化三个学生对象student1, student2, student3。每个对象都有自己特有的姓名、年龄、学号等信息。

假如这三个同学都是一个班的,那么他们一定在同一个教室上课。

之前在Student类中定义的成员变量,每个对象中都会包含一份(称之为实例变量),因为需要使用这些信息来描述具体的学生。而现在要表示学生上课的教室,这个教室的属性并不需要每个学生对象中都存储一份,而是需要让所有的学生来共享。在Java中,被static修饰的成员,称之为静态成员,也可以称为类成员,其不属于某个具体的对象,是所有对象所共享的。

7.2 static修饰成员变量

public class Student {
    private String name;
    private int age;
    private String stuNum;
    private static String classRoom;
    //...
}

【静态成员变量特性】

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

题目: 下面一段程序的输出结果是多少?
在这里插入图片描述

输出12

不管new多少个对象,从始至终只有一个count ,不管是通过哪一个对象访问的, 都是在对同一个count进行操作的。

7.3 static修饰成员方法

一般类中的数据成员都设置为private,而成员方法设置为public,那设置之后,Student类中classRoom属性如何在类外访问呢?

public class TestStudent {
  public static void main(String[] args) {   
    System.out.println(Student.classRoom);
  }
}
// 编译失败:
// Error:(10, 35) java: classRoom 在 extend01.Student 中是 private 访问控制

Java中,被static修饰的成员方法称为静态成员方法,是类的方法,不是某个对象所特有的。静态成员一般是通过静态方法来访问的。

public class Student{
    // ...
    private static String classRoom = "306";
    // ...
    public static String getClassRoom(){
        return classRoom;
    }
}
public class TestStudent {
    public static void main(String[] args) {
        System.out.println(Student.getClassRoom());
    }
}
输出:306

【静态方法特性】

  1. 不属于某个具体的对象,是类方法
  2. 可以通过对象调用,也可以通过类名.静态方法名(…)方式调用,更推荐使用后者
  3. 不能在静态方法中访问任何非静态成员变量
public static String getClassRoom(){
    System.out.println(this);
    return classRoom;
}
// 编译失败:Error:(35, 28) java: 无法从静态上下文中引用非静态 变量 this
public static String getClassRoom(){
    age += 1;
    return classRoom;
}
// 编译失败:Error:(35, 9) java: 无法从静态上下文中引用非静态 变量 age
  1. 静态方法中不能调用任何非静态方法,因为非静态方法有this参数,在静态方法中调用时候无法传递this引用.
public static String getClassRoom(){
    doClass();
    return classRoom;
}
// 编译报错:Error:(35, 9) java: 无法从静态上下文中引用非静态 方法 doClass()

在静态方法中,是不能访问普通的非静态成员变量和方法的 普通的非静态成员变量是依赖于对象的 要通过对象的引用去访问 而静态的成员方法是通过类名调用的 所以在通过类名调用静态方法时,是传不了this的,this是当前对象的引用,传不了this,我们就不知道当前对象是什么都不知道。
除非我们在这个静态方法中new一个对象,通过这个对象的引用去访问。
所以在static的成员方法中,是不存在this的。

  1. 静态方法无法重写, 不能用来实现多态。

  2. 在普通的成员方法里面可以调用静态得成员变量和成员方法。


在这里插入图片描述
age是被static修饰的,所以age是不依赖于对象的,age不是在person对象里面的age,age是属于类的。
person=null;代表person是不指向于任何对象的。


为什么在一个方法内部不能定义一个静态的成员变量。
在这里插入图片描述
定义时,加上static就是类变量,定义在方法里面就是局部变量了,它挺有脾气的,它不同意。

7.4 static成员变量初始化

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

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

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

public class Student {
    private String name;
    private int age;
    private String stuNum;
    private static String classRoom = "106";
    //...
}

8. 代码块


8.1 代码块概念以及分类

使用 {} 定义的一段代码称为代码块。根据代码块定义的位置以及关键字,又可分为以下四种:

  1. 普通代码块(不太能用的到)
  2. 非静态代码块(实例代码块/ 构造代码块)
  3. 静态代码块
  4. 同步代码块(后续线程部分)

8.2 普通代码块

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

public class Main{
    public static void main(String[] args) {
        { //直接使用{}定义,普通方法块
            int x = 10 ;
            System.out.println("x1 = " +x);
        }
        int x = 100 ;
        System.out.println("x2 = " +x);
    }
}
// 执行结果
// x1 = 10
// x2 = 100

这种用法较少见

8.3 构造代码块

构造块:定义在类中的代码块(不加修饰符)。也叫:实例代码块。构造代码块一般用于初始化类里面非静态的数据成员。构造代码块定义在类的里面,方法的外面。

public class Student {
    private String name;
    private int age;
    private String stuNum;
    private static String classRoom = "106";

//构造方法
    public Student(String name, int age, String stuNum, String classRoom) {
        this.name = name;
        this.age = age;
        this.stuNum = stuNum;
        this.classRoom = classRoom;
        System.out.println("构造方法被调用了....");
    }


//构造代码块
    {
        this.age = 100;
        System.out.println("构造代码块被调用了....");
    }
}
public class Test {
    public static void main(String[] args) {
        Student student1 =
                new Student("zhansgan", 21, "551453666", "1103");
    }
}
输出结果:
        构造代码块被调用了....
        构造方法被调用了....

和定义顺序没有关系,一定是先执行构造代码块,再执行构造方法。

8.4 静态代码块

使用static定义的代码块称为静态代码块。一般用于初始化静态成员变量。

public class Student {
    private String name;
    private int age;
    private String stuNum;
    private static String classRoom = "106";

    public Student(String name, int age, String stuNum, String classRoom) {
        this.name = name;
        this.age = age;
        this.stuNum = stuNum;
        this.classRoom = classRoom;
        System.out.println("构造方法被调用了....");
    }


    {
        this.age = 100;
        System.out.println("构造代码块被调用了....");
    }

    static {
        classRoom = "415";
        System.out.println("static{}......");
    }
}
public static void main(String[] args) {
    Student student1 =
            new Student("zhansgan", 21, "551453666", "1103");
}
输出结果:
     static{}......
     构造代码块被调用了....
     构造方法被调用了....

执行顺序和定义顺序无关,执行顺序:静态代码块—>实例代码块—>构造方法。


public static void main(String[] args) {
    Student student1 =
            new Student("zhansgan", 21, "551453666", "1103");
    System.out.println("==============");
    Student student2 =
            new Student("lisi", 21, "1576632", "1103");
}
输出结果:
        static{}......
	     构造代码块被调用了....
	     构造方法被调用了....
	     ==============
		 构造代码块被调用了....
		 构造方法被调用了....

可以看到当我们实例化两个学生对象的时候,静态代码块只执行了一次。

注意事项:

  1. 静态代码块不管生成多少个对象,其只会执行一次
  2. 静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的
  3. 如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行(合并)
  4. 实例代码块只有在创建对象时才会执行

静态代码块初识化静态数据成员,非静态代码块初始化非静态数据成员。

静态代码块中不会出现this.

10. 对象的打印

public class Student {
    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

public class Test {
    public static void main(String[] args) {
        Student student = new Student("zhangsan", 20);
        System.out.println(student);
    }
}

输出结果:Student@3b07d329

在这里插入图片描述
归根结底,程序在最后调用了一个toString()

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2167108.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

神经网络(四):UNet图像分割网络

文章目录 一、简介二、网络结构2.1编码器部分2.2解码器部分2.3完整代码 三、实战案例 一、简介 UNet网络是一种用于图像分割的卷积神经网络,其特点是采用了U型网络结构,因此称为UNet。该网络具有编码器和解码器结构,两种结构的功能如下&#…

程序执行过程中,报错debug errror damage :after normal block at

1.现象描述 Visual C 6.0运行一段程序,报错:debug errror damage :after normal block at(堆损坏了)。网上查了一下,说是内存访问越界。Debug模式下,点击忽略还能继续执行。 下面,我将通过断…

门牌风水大揭秘:如何通过八卦福·门牌提升居住运势

在现代家居风水理念中,门牌不仅是房屋的标识,更是影响居住运势的重要因素。八卦福门牌由于其独特的设计与深厚的文化内涵,已成为风水爱好者的新宠。通过合理运用八卦福门牌,我们可以有效提升家中的气场,增强运势。本文…

深入浅出 ResNet(残差网络)

一、引言 随着深度学习的发展,卷积神经网络(Convolutional Neural Networks, CNNs)在图像识别、目标检测等多个计算机视觉任务中取得了卓越的成绩。然而,随着网络深度的增加,训练变得更加困难,出现了梯度消…

2024网安周 | 百度安全深度参与,探索人工智能与数字安全的融合发展之路

9月9日-15日,2024年国家网络安全宣传周在全国范围内统一举行,本届网安周继续以“网络安全为人民,网络安全靠人民”为主题,由中央宣传部、中央网信办、教育部、工业和信息化部、公安部、中国人民银行、国家广播电视总局、全国总工会…

Javascript编译原理

JavaScript的编译原理是一个复杂但有序的过程,主要涉及分词(词法分析)、解析(语法分析)、代码生成以及执行等阶段。以下是对JavaScript编译原理的详细解析: chrome编译流程 1. 分词(词法分析&am…

宠物服务小程序的使用功能介绍

宠物服务小程序的使用功能丰富多样,旨在提升宠物主人的生活便利性和宠物的生活质量。以下是一些常见的宠物服务小程序使用功能: 1. 宠物服务商家展示与预约 商家信息展示:展示宠物服务商家的详细信息,包括店铺名称、地址、联系方…

企业为什么要上项目管理系统?项目管理的六大核心要素

随着企业规模的不断扩大和项目数量的增多,传统的手工管理方式已经无法满足企业在项目管理方面的需求。项目管理系统能够帮助企业实现项目信息的集中管理,将所有相关的项目信息(如任务、进度、预算、人员等)集中存储在一个平台上&a…

字节豆包C++一面-面经总结

talk is cheap show me the code lc206:链表反转:给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 class Solution { public:ListNode* reverseList(ListNode* head) {if(headnullptr||!head->next)return head…

线下线上陪玩系统要多少钱?该怎么搭建?

关于线下线上陪玩系统的价格,由于开发成本、功能复杂度、系统规模以及定制需求等因素的不同,价格差异较大,一般在几千元至几万元不等。具体价格需要根据实际需求和预算进行商议和定制。 搭建线下线上陪玩系统大致可以分为以下几个步骤&#…

推荐一款开源的链路监控系统

12.9k star,最强链路监控系统推荐,推荐 用过cat、pinpoint、skywalking等链路监控系统,各有优劣,但用的最多的还是pinpoint,工作6年,其中有4年都在用pinpoint,所以也比较熟悉,之前也…

戴尔笔记本电脑——重装系统

说明:我的电脑是戴尔G3笔记本电脑。 第一步:按照正常的装系统步骤,配置并进入U盘的PE系统 如果进入PE系统,一部分的硬盘找不到,解决办法:U盘PE系统——出现部分硬盘找不到的解决办法 第二步:磁…

年薪40W!转AI产品经理后,我明白了有人生的意义在哪了!

初识产品 目标有了,问题也有了 和很多人一样,毕业的时候比较迷茫,不知道自己喜欢什么行业、岗位… 就按照专业找了一个对口且擅长的算法工作,先着陆。 因为工作内容,我了解到了产品经理这个岗位,并对它…

掌握跟单与逼单技巧,大单成交不再是空谈!

1、精妙的迎宾艺术:解锁顾客心门的钥匙 在销售的殿堂里,每一位精明的导购都深知,与顾客的每一次接近,都是潜在成交乐章的序曲。掌握“五米关注、三米注视、一米搭话”的技巧,当顾客踏入店铺,目光流转于商品…

Syzkaller部署、使用与原理分析

文章目录 前言1、概述1.1、整体架构1.2、syz-manager进程1.3、syz-fuzzer进程1.4、syz-executor进程1.5、Generate进程1.6、Mutate进程 2、安装与使用2.1、源码安装2.1.1、部署系统依赖组件2.1.2、使用源码安装系统 2.2、使用方法2.2.1、下载编译测试内核2.2.2、配置测试虚拟机…

ElasticSearch分页查询性能及封装实现

Es的分页方式 fromsize 最基本的分页方式,类似于SQL中的Limit语法: //查询年龄在12到32之间的前15条数据 {"query":{"bool":{"must":{"range":{"user_age":{"gte":12,"lte":3…

【Java集合】Set 接口 —— HashSet 与 TreeSet 详解

Set接口和List接口一样,同样继承自Collection接口,它与Collection接口中的方法基本一致,并没有对Collection接口进行功能上的扩充,只是比Collection接口更加严格。与List接口不同的是,Set接口中的元素无序,…

Spring Boot使用配置方式整合MyBatis

文章目录 一、实战目标二、步骤概览1. 创建部门映射器接口2. 创建映射器配置文件3. 配置全局映射器4. 测试映射器接口 三、详细步骤1、创建部门映射器接口2、创建映射器配置文件3、配置全局映射器4、测试映射器接口 四、结语 一、实战目标 在本实战课程中,我们将学…

ChatGPT高级语音助手正式上线!OpenAI:50多种语言、9种声线可选

①OpenAI终于要面向其所有付费用户开放ChatGPT的类人高级人工智能(AI)语音助手功能——“高级语音模式”(AVM); ②所有付费订阅ChatGPT Plus和Team计划的用户,都将可以使用新的AVM功能,不过该模…

qt P2P网络通信(tcp、udp)

一、TCP Qt中的TCP通信是基于Qt框架中的网络模块实现的,主要涉及到QTcpSocket和QTcpServer两个类。TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,适用于需要可靠传输的应用场景,如文件传输…