Java封装详解,通俗易懂

lucien-ma 等级 591 0 0

封装

什么是封装?

封装是指将类的属性隐藏在内部,外部不能直接访问和修改,必须通过类提供的方法来完成属性的访问和修改。封装的核心思想就是尽可能把属性都隐藏在内部,对外提供方法来访问,我们可以在这些方法中田间逻辑处理来实现过滤,以屏蔽错误的数据的赋值。


封装的步骤

  1. 修改属性的访问权限,使得外部不能直接访问
  2. 提供外部可以直接调用的方法
  3. 在方法中加入属性控制逻辑
  • 所以我们需要将类中的成员变量的访问权限设置为私有(private),既只能在类的内部访问,外部无法直接访问该属性。
  • 同时提供外部可以调用的方法,方法同样需要设置访问权限,很显然需要将方法的访问权限设置为 public。
  • 在方法中添加确保属性值正确的逻辑代码。

封装完成后每一个属性都添加了两个方法: getter 和 setter,外部通过 getter 获取该属性的值,通过 setter 方法修改该属性的值


static 关键字

Java 程序要运行就必须在某个类中定义一个 main 方法作为程序的入口,我们会发现爱定义 main 方法时,有一个 static 关键字,那 static 表示什么呢? 为什么要用 static 来修饰 main 方法?本节内容为你一一揭晓。

static 表示静态或全局,可以用来修饰成员变量和成员方法以及代码块。

  • 要访问类中的成员变量或者成员方法,必须首先创建该类的对象,然后通过对象才能访问成员变量的成员方法,也就是说成员变量和成员方法的访问必须依赖于对象,这是常规的方式
  • 而 static 修饰的成员变量和成员方法独立于该类的任何一个实例对象,访问时不依赖于该类的对象。可以理解为被该类的所有实例对象共用,所以说它是全局。
  • 用 static 修饰的成员变量叫作静态变量页脚类变量, static 修饰的成员方法叫作静态方法,也叫作类方法。多个对象共用,内存只有一份
  • 没有被 static 修饰的成员方法叫作实例变量,没有被 static 修饰的成员方法叫作实例方法,一个对象对应一个,内存中有多份

既然静态成员变量和静态成员方法独立于任何一个实例对象,我们在访问这些静态资源时就无须创建对象,直接通过类即可访问。

class User{
    public static String name;
    public static void show(){
        System.out.println("这是一个User对象")
    }
}

public class Test{
    public static void main(String[] args){
        User.name = "张三";
        System.out.println(User.name);
        User.show();
    }
}

这种写法是没有问题的,不会报错


下面进行几个实例分析

代码 A

public class Test{
    private int id;
    public static void main(String[] args){
        Test test = null;
        for(int i = 0; i < 10; i++){
            test = new Test();
            test.id++;
        }
        System.out.println(test.id);
    }
}

分析:代码 A 的运行结果为1,因为此时的 id 为成员变量,每个实例化对象都拥有一个自己的 id。循环中创建了10个 Test 对象,内存中就会有10个 id,每个 id 都进行了加一操作,由0变为1,并且每次循环都会将新创建的 Test 对象赋给变量 test ,相当于更新了 10 次 test 的引用。 应为每次的 id 值都为 1 ,所以最终的结果也为 1

代码 B

public class Test{
    private static int id;
    public static void main(String[] args){
        Test test = null;
        for(int i = 0; i < 10; i++){
            test = new Test();
            test.id++;
        }
        System.out.println(test.id);
    }
}

分析:代码 B 的运行结果为 10,因为此时的 id 是静态变量,属于类不属于对象,内存中只有一份,所以任何时候对 id 的修改都会作用在同一个变量,循环中共执行了 10 次 id++,所以 id 的值为 10

代码 C

public calss Test{
    private static int id;
    public static void main(String[] args){
        for(int i = 0; i < 10; i++){
            Test.id++;
        }
        System.out.println(Test.id);
    }
}

分析: 代码 C 的运行结果为 10 ,具体的原因同代码 B,唯一的却别在于代码 B 是通过实例化对象访问静态变量的, 代码 C 是通过类来访问静态变量的,运行结果没有区别。

我们在使用 static 修饰成员方法时需要注意,静态方法中不能使用 this 关键字,不能直接访问所属类的实例变量和实例方法,可直接访问类的静态变量和静态方法。若要访问类的实例变量和实例方法,必须先实例化类的对象,然后通过对象去访问

static 修饰代码块

重要:

static 除了可以修饰成员变量和成员方法之外,还可以修饰代码块,被 static 修饰的代码块被叫作静态代码块。静态代码块的特点是只执行一次,在什么时候执行呢?当该类被加载到内存时执行,不需要手动调用,他会自动执行,在什么时候类第一次被加载?这里我们需要简单地阐述一下 Java 加载类的机制。我们知道 Java 代码时偶类构成的,但是真正运行时是通过对象和对象之间的相互调用关系来完成需求的。即在程序运行时,需要在内存中创建多个对象,对象怎么创建?需要通过类来创建,类是模板,同时这个模板只需要加载一次,所以程序在运行时,首先会讲程序中用到的类加载到内存中,并且只加载一次。然后通过类来创建多个对象以完成具体的业务。被加载到内存中的类叫作运行时类,静态代码块就是在加载类的时候执行的,因为类只加载一次,所以静态代码块也只执行一次。简单的理解,当代码中第一次出现某个类时,就会执行静态代码块,静态代码块只能访问静态变量和静态方法

public class User{
    public static int num;
    static{
        num++;
        System.out.println("执行了静态代码块");
    }
}

public class Test{
    public static void main(String[] args){
        User user = new User();
        User user2 = new User();
        User user3 = new User();
        System.out.println(user.num);
        System.out.println(user2.num);
        System.out.println(user3.num);
    }
}

运行结果应该为:


执行了静态代码块

1

1

1


通过结果可以得出结论:虽然创建了 3 个 User 对象,但是静态代码块只执行一次。如果有多个静态块同时存在,则按先后顺序执行,类的构造方法用于初始化类的实例,类的静态代码块用于初始化类,给类的静态变量赋值。

收藏
评论区

相关推荐

Caused by: java.lang.RuntimeException: xxl-job jobhandler naming conflicts.
xxljob报这个错误,是因为jobHandler名字重复了,记录一下。
java.lang.IllegalStateException: Ambiguous mapping found. Cannot map 'XXXXX' bean
mvc项目启动报这个错原因:rest/controller中映射的地址重复
HelloWorld
Finally find this place.Nice to meet you all.关注helloworld社区也有一段时间了,由于是新晋社区资源较少,一直没有怎么真正的去使用,只是单纯觉得界面美观简洁,符合自己的审美,偶尔逛逛而已。今天终于有时间可以可以坐下来说说话,都说程序员的第一行输出是helloworld,在这个社区的第一篇博客我也
垃圾回收机制
GC标记算法 对象被判定为垃圾的标准:没有被其他对象引用 引用计数算法: 判断对象的引用数量: 通过判断对象的引用数量来决定对象是否可以被回收 每个对象实例都有一个引用计数器,被引用则1,完成引用则1 任何引用计数为0的对象实例可以被当做垃圾收集 优点:执行效率高,程序执行受影响较小。
如何设计一个数据库?
设计两个大模块,存储(文件系统)与程序的实例模块。程序的实例模块划分为:存储管理,缓存机制,SQL解析,日志管理,权限划分,容灾机制,索引管理,锁管理。 为什么使用索引? 假设使用原始的全表查询,那么对于小量数据可能速度并没有影响,但是在大量数据的情况下会使得速度很慢。而索引,则类似于字典中的偏旁部首,加快了查询的效率。 二叉
第一天:今天学spring的时候遇到一个错误
具体错误如下:Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'testDao' is defined at org.springframework.beans.factory.support.D
Java 基础 SDK区别简介
1. Java SE(Java Platform,Standard Edition),应该先说这个,因为这个是标准版本。 Java EE (Java Platform,Enterprise Edition),java 的企业版本 Java ME(Java Platform,Micro Edition),java的微型版本。 1). JavaSE 可以
Java 高级应用编程 第一章 工具类
**一、Java API** **Java API简介** 1、API (Application Programming Interface) 应用程序接口 2、Java中的API,就是JDK提供的各种功能的Java类 3、JDK帮助文档   JAVA\_API\_CN.chm   官网地址http://www.oracle.com/tech
java 配置環境
JAVA\_HOME                                      C:\\Java\\jdk1.8.0\_11 PATH:                                                 %JAVA\_HOME%\\bin;%JAVA\_HOME%\\jre\\bin; CLASSPATH: 
java基础知识随身记
2018年11月12日20:51:35 一、基础知识: 1、JVM、JRE和JDK的区别: JVM(Java Virtual Machine):java虚拟机,用于保证java的跨平台的特性。   java语言是跨平台,jvm不是跨平台的。 JRE(Java Runtime Environment):java的运行环境,包括jvm+java的核心类
java学习第一步
Java SE 磨刀不误砍柴工,工欲善其事必先利其器,咱们先搞好硬件配置,才能顺利的搞好Java学习 阶段一 1、认识Java 2、java发展史及用户 3、配置Java环境 4、JDK8下载安装 5、配置环境变量     JAVA\_HOME配置         java\_home配置两种方法:                 1、J
java的特性
java的特性 ======= 1、Java语言是简单的 2、Java语言是面向对象的 3、Java语言是分布式的 4、Java语言是健壮的 5、Java语言是安全的 6、Java语言是可移植性的 7、Java语言是解释型的 8、Java语言是多线程的 9、Java语言是动态的语言   **Java语言是简单的:**  
How to switch java version on ubuntu 20.04
* View all java versions lwk@qwfys:~$ update-java-alternatives --list java-1.11.0-openjdk-amd64 1111 /usr/lib/jvm/java-1.11.0-openjdk-amd64 java-1.8.0-ope
Jmeter使用过程中遇到的问题
**问题一:** 已安装java,也配置了java环境变量,但打开jmeter时提示:Not able to find Java executable or version. **解决方法:** 在jmeter.bat文件前面加上以上两句: SET JAVA\_HOME=C:\\Program Files\\Java\\jdk1.7.0\_51 S
Linux中查看jdk安装目录、Linux卸载jdk、rpm命令、rm命令参数
一、查看jdk安装目录 ----------- [root@node001 ~]# whereis java java: /usr/bin/java /usr/local/java #java执行路径 [root@node001 ~]# which java /usr/bin/java #查看JDK安装路径