当前位置: 首页 > news >正文

JavaSE知识分享——类和对象(下)

若文中出现疏漏、不足之处,望广大读者批评指正

接下来我会持续更新JavaSE、Java数据结构、MySQL、JavaEE、微服务、Redis等等内容的知识点整理。后续我也会精心制作算法解析、项目经验系列内容,内容绝对干货。相信这些文章能够成为我和大家的“葵花宝典”,喜欢的话就关注一下吧!敬请期待!

文章目录

  • 一、封装
    • 认识封装
    • 访问限定符
    • 认识封装中的包
      • 导入包中的类
      • 自定义包
  • 二、static关键字
    • static修饰成员变量
    • static修饰成员方法
    • static修饰成员变量的初始化
  • 三、代码块
    • 代码块概念以及分类
    • 普通代码块及构造代码块
    • 静态代码块
  • 四、对象的打印
    • 默认行为:
    • 重写 toString()

一、封装

认识封装

  • 面向对象程序三大特性:封装、继承、多态。而类和对象阶段,主要研究的就是封装特性。

何为封装呢?简单来说就是套壳屏蔽细节。

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

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

访问限定符

  • Java中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的方法结合在一起,更符合人类对事物的认知,而访问权限用来控制方法或者字段能否直接在类外使用。
  • Java中提供了四种访问限定符:
    在这里插入图片描述
    注:在 Java 中,局部变量不能使用访问修饰符(如 public、private、protected)或 static 等修饰符。唯一允许的修饰符: final
  • 局部变量可以声明为 final ,表示该变量只能被赋值一次(常量)

认识封装中的包

  • 为了更好的管理类,把多个类收集在一起成为一组,称为软件包。包是对类、接口等的封装机制的体现,是一种对类或者接口等的很好的组织方式,比如:一个包中的类不想被其他包中的类使用。
  • 包还有一个重要的作用:在同一个工程中允许存在相同名称的类,只要处在不同的包中即可。
  • 包对应着文件夹,可在每个包中建立多个.Java文件。文件夹是包在文件系统中的物理存储形式,二者是“逻辑组织”与“物理载体”的关系,确实不是直接等同。

导入包中的类

使用 import语句导入包

import java.util.Date;
  • 然后就可以直接使用 Date 这个类
Date date = new Date();
// 得到一个毫秒级别的时间戳
System.out.println(date.getTime());
  • 不使用import导入包的话就只能这样写,很麻烦:
java.util.Date date = new java.util.Date();
// 得到一个毫秒级别的时间戳
System.out.println(date.getTime());
  • 如果使用 import java.util.* 的话,就会导入java.util 包中的所有类。但是还是更建议显式的指定要导入的类名. 否则还是容易出现冲突的情况.

可以使用import static导入包中静态的方法和字段:

import static java.lang.Math.*;
public class Test {
public static void main(String[] args) {
double x = 30;
double y = 40;
// 静态导入的方式写起来更方便一些.
// double result = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
double result = sqrt(pow(x, 2) + pow(y, 2));
System.out.println(result);
}
}

注意事项: import 和 C++ 的 #include 差别很大. C++ 必须 #include 来引入其他文件内容, 但是 Java 不需要.import 只是为了写代码的时候更方便,不用再像上述那样麻烦地导入包中的类了。

自定义包

基本规则

  • 包名要和代码路径相匹配. 例如创建com.bit.demo1 的包, 那么会存在一个对应的路径 com/bit/demo1 来存储代码.
    如果一个类没有 package 语句, 则该类被放到一个默认包中.

注意:

  • com.example 是一个完整的包名。但从目录层次看,它依赖于父目录 com 的存在。在逻辑上, com 和 com.example 是两个不同的包。

  • com.example包中需要时是否需要导入父包中的类? 需要。必须使用 import 语句,就像导入任何一个其他无关的包(例如 import java.util.List; )一样。

  • 额外限制:当然即使导入了,目标类(如 com.Tool )还必须被声明为 public ,否则在包外依然没有访问权限。

二、static关键字

static修饰成员变量

  • 之前在Student类中定义的成员变量,每个对象中都会包含一份(称之为实例变量)。

  • 在Java中,被static修饰的成员,称之为静态成员,也可以称为类成员,其不属于某个具体的对象,也不用依靠对象的引用来访问,是所有对象所共享的。

  • static修饰的成员变量,称为静态成员变量,静态成员变量最大的特性:不属于某个具体的对象,是所有对象所共用的。

静态成员变量特性:

  1. 不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中
  2. 通过类名来访问是规范的,也可以通过对象访问,但一般更推荐使用类名访问
  3. 类变量存储在方法区当中,这是与普通成员变量最显著的区别。普通成员变量需要依靠对象的引用来访问,都是由类来创建一个引用变量存储对象的地址,以此来访问对象,此引用变量在栈区分配的内存。由对象存储真实数据(成员变量、及成员方法实现),对象在堆区分配内存。而如果是类变量,则直接与普通变量分离,在内存中的方法区分配空间储存数据,所以也就完全不依赖对象,即使还没有通过 new 实例化对象,照样可以使用,通过类名访问方法区的类变量即可,而这块空间也就是所有此类所实例化的对象公用的,压根就不是和对象一样在堆区。
  4. 生命周期伴随类的一生(即:随类的加载而创建,随类的卸载而销毁)

static修饰成员方法

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

  1. 不属于某个具体的对象,是类方法
  2. 可以通过对象调用,也可以通过类名.静态方法名(…)方式调用,更推荐使用后者。
  3. 不能在静态方法中访问任何非静态成员变量,静态方法只能访问静态变量。
  4. 静态方法中不能直接调用任何非静态方法,因为非静态方法有this参数,在静态方法中调用时候无法传递this引用。静态方法不能直接调用非静态方法是因为缺少隐式的 this 引用。但通过创建对象实例来调用是完全合法的,因为对象提供了必要的上下文。
    关键点说明:
  • this 引用的作用:实例方法隐含一个 this 参数,指向调用该方法的对象。静态方法没有 this ,因此不能直接调用实例方法。

  • 通过对象实例调用:当实例化对象后(new一个对象),该对象就有了完整的实例上下文,通过对象调用实例方法时, this 自然指向该对象。

static修饰成员变量的初始化

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

  • 静态成员变量的初始化分为两种:就地初始化(定义时就直接赋值)和静态代码块初始化。

三、代码块

代码块概念以及分类

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

  1. 普通代码块
  2. 构造块
  3. 静态块

还有同步代码块(这个涉及到后续知识)

普通代码块及构造代码块

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

  • 构造代码块:定义在类中的代码块(不加修饰符)。也叫:实例代码块。构造代码块一般用于初始化实例成员变量

注:构造代码块的核心作用是抽取所有构造方法的公共初始化逻辑,避免重复代码;而构造方法则负责实现各自独特的初始化逻辑,二者分工不同。

简单来说,构造代码块是“通用模板”,构造方法是“个性化定制”。比如一个 Person
类,所有对象初始化时都需要“初始化血型”(公共逻辑,写在构造代码块),但不同对象的“姓名、年龄”不同(独特逻辑,写在构造方法)。

静态代码块

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

public class Student{
private String name;
private String gender;
private int age;
private double score;
private static String classRoom;
//实例代码块
{
this.name = "xxx";
this.age = 12;
this.gender = "man";
System.out.println("I am instance init()!");
}
// 静态代码块
static {
classRoom = "xxx306";
System.out.println("I am static init()!");
}
public Student(){
System.out.println("I am Student init()!");
}
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student();
}
}

注意事项:

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

四、对象的打印

在 Java 中,当你想直接打印一个对象时,会自动调用该对象的 toString() 方法。

默认行为:

  • 所有 Java 对象都继承自 Object 类,Object 类有一个 toString() 方法
  • toSrting默认实现返回: 类名@哈希码 (十六进制),例如: com.example.Person@1b6d3586

打印时的自动调用:

Person person = new Person("张三", 25);
System.out.println(person); // 实际上相当于 System.out.println(person.toString());
//输出结果就是一串哈希码(哈希码不是地址)

重写 toString()

默认的 toString() 返回的信息对调试不太友好,所以通常我们会在当前类中重写它:

public class Person {private String name;private int age;// 构造方法等其他代码...@Overridepublic String toString() {return "Person{name='" + name + "', age=" + age + "}";}
}

注:重写时方法签名必须完全匹配!不能搞成重载了。

//正确重写
public String toString() {//实现}

这样打印时就会显示更有意义的信息: Person{name='张三', age=25} ,toString()方法返回什么就打印什么。

觉得文章对你有帮助的话就点个赞,收藏起来这份免费的资料吧!也欢迎大家在评论区讨论技术、经验

http://www.dtcms.com/a/549844.html

相关文章:

  • 企业级K8s部署:Helm+Kustomize混合策略实现零配置漂移与10分钟多环境发布
  • 上海人才中心昆明网站词排名优化
  • jQuery Growl - 实用且易于集成的通知插件
  • Manage Provisioning Access 功能详解
  • 龙岗在线网站建设网络销售网站外包
  • NVIDIA NCCL 源码学习(十六)- nccl的ibgda(GIN)
  • 深度优先搜索(DFS)
  • 协会网站建设方案wordpress 以前文章灯箱
  • PCIe学习笔记
  • 处理 rstudio-server 卡死问题
  • C 盘清理技巧分享
  • 零基础小白如何高效入门项目管理?
  • 安装与切换Rust版本
  • 云服务器建立多个网站文山知名网站建设公司
  • 深圳网站建设网站制作网站推广vps一键安装wordpress
  • 定制网站和模板建站室内设计培训网课
  • 云免网站空间自己怎么做网站模块
  • 佰力博检测与您探讨压电薄膜介电温谱测试的目的
  • 所有权转移在函数调用中的表现:Rust 内存安全的函数边界管理
  • WebRTC学习中各项概念笔记
  • 外包网站问些什么问题一个网站可以做几级链接
  • 网站开发商怎么关闭图片显示上海网站外包
  • K8s练习
  • 订阅飞书审批事件
  • 网站被降权怎么办河北政务服务网
  • ELEMENT_ERF 1150X_CASSETTE装配(ERF1150 OR EDT1150多国语言)
  • 网站备案撤销再备案英国做电商网站有哪些方面
  • 网站开发 税率wordpress 网站打不开
  • 永乐视频网页入口 - 免费高清影视在线观看网站
  • 砂轮姿态调整的几何艺术:摆角与抬角变换的数学原理