Java类与对象详解(3)

news2024/12/23 7:56:50

目录

封装

封装的概念

访问限定符

封装扩展之包

包的概念

导入包中的类

自定义包

基本规则

包的访问权限控制举例

常见的包

static 成员

static 修饰成员变量

static修饰成员方法 

static 成员变量的初始化

代码块

代码块的概念及其分类

普通代码块

构造代码块

 静态代码块


封装

封装的概念

我们知道,面向对象程序的三大特性为:封装,继承,多态。而类和对象阶段,主要研究的是封装特性,何为封装呢?简单来说就是套壳屏蔽细节。在java语法中,就是指被private修饰的成员变量和成员方法。(private一会会详细介绍)。

那么为什么用private修饰了,我们就说实现了封装了呢?来看下面一个代码:

class Peo{
    private int age;
    private String name;
    public Peo(){

    }
    public Peo(int age, String name){
        this.age = age;
        this.name = name;
    }
    public void sleep(String name){
        System.out.println(this.name + "正在睡觉");
    }
}


public class test1 {
    public static void main(String[] args) {
        Peo p = new Peo();
        //直接调用?
        p.name = "马牛逼";
    }
}

这里出现了一个错误:

原因是这里Peo类中name被private 修饰了(等同于name被屏蔽了,用户不知道这个p对象中的属性),所以不能直接调用name。通俗的来说:就是p这个对象具有隐私权,根据宪法(private),我们无法侵犯它的隐私(name这个属性)。 

访问限定符

Java中主要通过类和访问权限进行封装:类可以将数据以及封装数据的方法结合到一起,更符合人类对事物的认知,而访问权限用来控制方法或者字段能否直接在类外使用。Java中提供了四种访问限定符:

 比如:

public:可以理解为一个人的外貌特征,谁都可以看得到。

default:对于自己家族中(同一个包中)不是什么秘密,对于其他人就是隐私了(默认权限)

private:只有自己知道,其他人都不知道

说明:

protected主要用在继承中,继承部分会详细介绍

default权限指:前面不写访问限定符的默认权限

访问权限除了可以限定类中成员的可见性,也可以限制类的可见性

注意:一般情况下成员变量设置为private,成员方法设置为public.

封装扩展之包

包的概念

在面向对象体系中,提出了软件包的概念,即:为了更好地管理类,把多个类放在一起成为一组,称为软件包。有点类似于目录。比如管理电脑中歌曲的方式如下:

 在Java中也引入了包,包是对类,接口等封装机制的体现,是一种对类或者接口等很好的组织方式,比如:一个包中的类不想被其他包中的类使用。包还有一个重要的作用:在一个工程中允许出现相同名称的类,只要在不同包中即可

导入包中的类

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

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

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

import java.util.Date;

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

如果要使用java.util中的其它类,可以使用import java.util.*;

但是还是更建议显式地指定导入java.util的其它类。否则可能会出现冲突的情况,举个栗子:

import java.util.*;
import java.sql.*;

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

这里有这样的问题:

因此这种情况应该使用完整的类名。

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

import static java.lang.Math.*;

public class test3 {
    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);
    }
}

自定义包

基本规则

1.在文件的最右上方加上一个package语句指定该代码在哪个包中。

2.包名需要尽量指定生成唯一的名字,通常会用公司域名的颠倒形式(eg:com.air.demo)

3.包名要和代码路径相匹配,例如创建com.air.demo的包,那么就会存在一个对应路径com/air/demo来存储代码

4.如果没有package的语句,则该类被放在一个默认包中。 

包的访问权限控制举例

Computer位于Demo1中,TestComputer位于Demo2中

package Demo1;

public class Computer {
    private String cpu;//cpu
    private String memory;//内存
    public String screen;//屏幕
    String brand;//品牌

    public Computer(String brand, String cpu, String memory, String screen) {
        this.brand = brand;
        this.cpu = cpu;
        this.memory = memory;
        this.screen = screen;
    }

    public void Boot() {
        System.out.println("开机---");
    }

    public void PowerOff() {
        System.out.println("关机---");
    }

    public void SurfInternet() {
        System.out.println("上网---");
    }
}


package Demo2;

import Demo1.Computer;
public class TestComputer {
    public static void main(String[] args) {
        Computer p = new Computer("MAC","M1", "8G", "13*14");

        System.out.println(p.screen);
        //System.out.println(p.cpu);//报错:cpu是私有的,不允许被其它类访问
        //System.out.println(p.brand);//报错:brand是default,不允许被其他的包访问
    }
}

//注:如果去掉Computer类之前的public 修饰符,代码也会编译失败




常见的包

1.java.lang:系统常用的基础类(String, Object),此包从JDK1.1后自动导入

2. java.lang.reflect:java 反射编程包
3. java.net:进行网络编程开发包
4. java.sql:进行数据库开发的支持包
5. java.util:是java提供的工具程序包,(集合类等) 非常重要
6. java.io:I/O编程开发包

static 成员

static 修饰成员变量

我们之前讲过:实例变量是指定义在类中的变量,每个类的实例(对象)都会有自己的一组实例变量,那么什么又是static 修饰的成员变量呢?

static修饰的成员变量,称为静态成员变量,静态成员变量最大的特性:不属于某个具体的对象,是所有对象所共享的。(比如创建几个学生对象,他们都是一班的,那么这个班级是共享的,是static 修饰的成员变量)。

静态成员变量的特性

1.不属于某个具体的对象,是类的属性,为所有对象共享的,不存储在某个对象的空间中

2.既可以通过对象访问,也可以通过类名访问,但一般更推荐类名访问

3.类变量存储在方法区中

4.生命周期伴随着类的一生(即:随类的加载而创建,随类的销毁而卸载

举个栗子:

public class Student {
    public String name;
    public String gender;
    public int age;
    public double score;
    public static String classroom = "303";

    public static void main(String[] args) {
        //静态变量可以直接通过类名来访问
        System.out.println(Student.classroom);

        Student s1 = new Student();
        Student s2 = new Student();
        //也可通过类名来访问,不过classroom是两个对象共享的
        System.out.println(s1.classroom);
        System.out.println(s2.classroom);
    }
}

通过调试,在监视窗口可以看到,静态成员并没有存储到某个具体的对象中

static修饰成员方法 

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

class Student {
    private String name;
    private String gender;
    private int age;
    private double score;
    private static String classRoom = "103";

}

public class TestStudent{
    public static void main(String[] args) {
        System.out.println(Student.classRoom);
    }
}

//java: classRoom 在 Demo2.Student 中是 private 访问控制

那static 属性应该如何访问呢?

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

举个栗子:

public class Student {

    private static String classRoom = "103";

    public static String getClassRoom() {
        return classRoom;
    }

    public static void main(String[] args) {
        System.out.println(Student.classRoom);
    }
}

显而易见静态方法可以轻松解决问题,下面我们来说一下静态方法的特性:

1.与静态成员变量相同,不属于某个具体的对象,属于类

2.可以通过对象调用,也可以通过类名.静态方法名的方式调用,更推荐后者

3.不能在静态方法中使用任何非静态变量

4.静态方法中不能调用任何非静态方法,因为非静态方法有this参数,在静态方法中不能传递this引用

static 成员变量的初始化

注意:静态变量一般不在构造方法中初始化,因为静态变量不属于任何对象,构造方法中初始化的是对象相关的实例属性。

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

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

2.静态代码块初始化:见下文:

代码块

代码块的概念及其分类

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

1.普通代码块

2.构造块

3.静态块

4.同步代码块

普通代码块

定义:定义在方法内的代码块

public class Test1 {
    public static void main(String[] args) {
        {//直接用{}定义普通代码块
            int x = 10;
            System.out.println(x);
        }
        int x = 100;
        System.out.println(x);
    }
}

这种用法偏少

构造代码块

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

构造代码块一般适用于初始化实例成员变量

class Student1 {
    //实例成员变量
    private String name;
    private String gender;
    private int age;
    private double score;

    //构造方法
    public Student1() {
        System.out.println("I am Student init()!");
    }

    //实例代码块
    {
        this.name = "bit";
        this.age = 12;
        this.gender = "man";
        System.out.println("I am instance init()");
    }

    public void show(){
        System.out.println("name:" + name +",age:" + age + ",gender:" + gender);
    }

    public static void main(String[] args) {
        Student1 stu = new Student1();
        stu.show();
    }
}

 静态代码块

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

public class Student2 {
    private String name;
    private String gender;
    private int age;
    private double score;
    private static String classRoom;
    //实例代码块
    {
        this.name = "bit";
        this.age = 12;
        this.gender = "man";
        System.out.println("I am instance init()");
    }

    //静态代码块
    static {
        classRoom = "103";
        System.out.println("I am static init()");
    }

    //构造方法
    public Student2(){
        System.out.println("I am Student init()");
    }

    public static void main(String[] args) {
        Student2 s1 = new Student2();
        Student2 s2 = new Student2();
    }
}

 

 通过上面的代码我们可以总结出如下规律:

1.静态代码块不管实例化出多少对象,都只执行一次

2.(以只创建一个对象为例)执行代码块的基本顺序为:静态代码块->实例代码块->构造方法

3.静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的

4.如果一个类中包含多个代码块/实例代码块,它们会合到一块

5.实例代码块只有创建了对象才会执行,而静态代码块不创建对象也可以

​​​​​​​

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

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

相关文章

旧版本docker未及时更新,导致更新/etc/docker/daemon.json配置文件出现docker重启失败

一、背景 安装完docker和containerd之后,尝试重启docker的时候,报错如下: systemctl restart dockerJob for docker.service failed because the control process exited with error code. See “systemctl status docker.service” and “…

Vue学习:创建Vue

一、安装Node.js和NPM 1.安装node.js 从node.js官网下载并安装node.js 网址: Download | Node.js 2.双击” node-v8.1.2-x64.msi”开始安装 至此Node.js已经安装完成,可以先进行下简单的测试安装是否成功了,后面还要进行环境配置在键盘按…

理解 Go 中的切片:append 操作的深入分析(篇1)

理解 Go 语言中 slice 的性质对于编程非常有益。下面,我将通过两个代码示例来解释切片在不同函数之间传递并执行 append 操作时的具体表现。 本篇为第 1 篇,当切片的容量 cap 充足时 第一份代码 slice1 的初始长度为 3,容量为 10 func main()…

win10电脑右下角不显示电脑图标,但是能正常上网,怎么解决?

一、问题描述 win10系统更新后,电脑右下角不显示小电脑图标,但是能正常上网,而且用命令测试时显示的是192打头的网址。 二、解决方法 运行命令提示符窗口,在命令提示符中输入:netsh winsock reset( 如果提示…

汇编知识点之磁盘文件存取技术

1.文件代号式磁盘存取 (1)两个重要的表 (2)简要说明: 文件代号式存取方式将有关文件的各种信息都包括在DOS中。 在处理指定文件时必须使用一个完整的路径名,一旦文件的路径名被送入操作系统,就被赋予一个简单的文件…

使用chatGPT规划在北京的生活预算

介绍 通过使用chatGPT大概预算自己的生活支出和收入,搞清楚多少的收入能在一个城市过的比较舒服,更好的去规划自己的职业和未来。本文以一线城市为例。 什么是生活成本指数? 生活成本指数是对居住在某个地点的普通人预期的不同费用成本的广泛…

十秒搞懂ER图中的对应关系

十秒搞懂ER图中的对应关系 ER图是什么实体是什么关系如何确认实体间的关系简单总结 ER图是什么 实体关系图(Entity-Relationship Diagram,简称ER图)是一种图形化的工具,用于表示数据库中不同实体之间的关系和连接。ER图是数据库设…

Ubuntu系统没有声音

现象 新按转的Ubuntu系统没有声音,怀疑是声卡选择的问题 解决方法 1、在终端输入alsamixer命令 2、按下F6键选择声卡 不要选择NVidia,而是选择HD-Audio 3、将所有音量调到最大,把disable调成enable

2023-08-14 linux 串口终端输入长命令不换行,覆盖前面内容,stty命令设置串口终端行列数

一、linux 串口终端输入长命令不换行,覆盖前面内容,现象如下图: 二、解决方法:用stty 命令设置行列数 stty columns 200 stty rows 10三、参考文章 https://www.cnblogs.com/goloving/p/15170537.html 常用Linux串口设备操作命…

Tomcat多实例部署及nginx+tomcat的负载均衡和动静分离

Tomcat多实例部署 安装 jdk、tomcat(流程可看之前博客) 配置 tomcat 环境变量 [rootlocalhost ~]# vim /etc/profile.d/tomcat.sh#tomcat1 export CATALINA_HOME1/usr/local/tomcat/tomcat1 export CATALINA_BASE1/usr/local/tomcat/tomcat1 export T…

达梦数据库(dm8) 在Centos7环境 单节点安装

国产数据库-达梦 一、环境详情二、Centos7 参数优化三、创建用户四、开始安装 当前安装 在指定版本环境下 测试,仅供参考 一、环境详情 软件版本 软件版本下载地址Centos 7CentOS Linux release 7.9.2009 (Core) x86达梦数据库dm8_20230418_x86_rh6_64.zip 节点分配…

html2canvas生成图片地址Base64格式转成blob在转成file(二进制)可正常发送(保姆教程,复制粘贴可用)

开始: 最终结果: 1. html2canvas方法生成的图片地址已Base64编码形式放在img标签src中可直接展示生成的图片(注意页面标签获取位置,还有个setTimeout页面渲染需要时间) setTimeout(function () {var result {};v…

最新Anaconda安装-保姆级教程

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一、Anaconda下载 二、使用步骤 手动配置环境变量 (上面选择just me和默认配置的可以跳过这一步) 简要说明五条路径的用途:这五…

Spring(三):Spring中Bean的生命周期和作用域

前言 在 Spring 中,那些组成应用程序的主体及由 Spring IOC 容器所管理的对象,被称之为 bean。简单地讲,bean 就是由 IOC 容器初始化、装配及管理的对象,除此之外,bean 就与应用程序中的其他对象没有什么区别了。而 b…

金蝶云星空和易快报单据接口对接

金蝶云星空和易快报单据接口对接 来源系统:易快报 易快报是敏捷的企业报销费控与聚合消费平台,为企业提供移动报销、聚合消费、全程费控、预算管理、发票管理等一站式解决方案。同时,易快报可集成多家银行及第三方支付平台,打通对公对私付款&…

GD32F103VE使用软件扫描读取多通道AD值

GD32F103VE使用软件扫描读取多通道AD值。 GD32F103的ADC为12位AD转换器,ADC转换结果保存在16位数据寄存器中; 模拟输入通道: 16个外部模拟输入通道; 1个内部温度传感器通道(Vsense) 1个内部参考电压输入通道(VrefInt) ADC的VDDA电源引脚需要接入3.3V; ADC输入模拟…

Algorithem Review 5.2 图论

网络流 设源点为 s s s,汇点为 t t t,每条边 e e e 的流量上限为 c ( e ) c(e) c(e),流量为 f ( e ) f(e) f(e)。割 指对于某一顶点集合 P ⊂ V P \subset V P⊂V,从 P P P 出发指向 P P P 外部的那些原图中的边的集合&a…

WMS系统出库操作规范:提高效率与准确性的关键

WMS系统出库管理是指通过仓库管理系统(Warehouse Management System,简称WMS)对仓库中的货物进行出库操作的管理过程。WMS系统是一种利用自动化和数字化技术提高仓库管理效率和准确性的工具,它提供了对仓库内货物的全面控制和可视…

CentOS7源码安装MySQL详细教程

😊 作者: Eric 💖 主页: https://blog.csdn.net/weixin_47316183?typeblog 🎉 主题:CentOS7源码安装MySQL详细教程 ⏱️ 创作时间: 2023年08月014日 文章目录 1、安装的四种方式2、源码安装…

selenium的环境搭建

selenium是一个自动化测试框架,主要针对web项目进行UI自动化。他的工作原理如下图: 那么我们在学习selenium之前就需要就行一个环境的搭建,就是要下载配置我们的浏览器驱动。进入正题: CNPM Binaries Mirror 在网站中选择对应自…