OOP之封装全过程(Java)

 更新时间:2025年09月23日 09:23:05   作者:鱼子酱Yuu_  
文章讲解了封装作为面向对象三大特性之一,通过private修饰符和getter/setter方法实现数据隐藏,Java利用访问权限(private/default/protected/public)控制成员可见性,并介绍了包的组织管理作用及静态成员的初始化与执行顺序

面向对象语言三大特性封装、继承、多态。本篇文章将讲述封装有关...何为封装?! 简而言之就是套壳屏蔽细节...

概念

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

注:接口有两层含义 -> ①.方法 ②.真正的接口(语法);此处加粗的接口为第一层含义

如下列代码,将成员变量name,age用private修饰后,外界不可直接获取、修改name和age,那么通过创建公开的方法getName()、setName()、getAge()...来对封装的成员变量进行操作

public class Person {
      private String name;
      private int age;
    
      public String getName(){
           return this.name;
      }

      public void setName(String name){
           this.name = name;
      }
}
Person person = new Person();
person.setName("张三");
System.out.println(person.getName());//打印张三
  • 快捷生成get()/set()方法 -->
  • 鼠标右键Generate --> Getter(只要get()) 
  • Setter(只要set())   --> 可选中全部属性
  • Getter and Setter --> ok --> 会自动生成get()/set()

因此,从语法上来说,封装就是被private修饰的成员变量或者成员方法,且只能在当前类当中使用。

访问限定符

JAVA中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的方法结合在一起,而访问权限用来控制方法或者字段能否直接在类外使用

JAVA提供了四种访问限定符:

No范围privatedefaultprotectedpublic
1同一包中的同一类
2同一包中的不同类
3不同包中的子类
4不同包中的非子类
  • private: 私有的(只有自己知道,其他人都不知道)
  • default: 默认的,包访问权限 (!不要在成员/方法前加default,什么都不写即为默认)
  • protected: 受保护的 (主要用在继承中,继承部分详细介绍)
  • public: 公有的(哪都能用)

注:

  • ①.访问权限除了可以限定类中成员的可见性,也可以控制类的可见性
  • ②.一般情况下,成员变量设置为private,成员方法设置为public

封装扩展之包

包的概念

为了更好的组织和管理类,把多个类收集在一起成为一组,称为软件包。

导入包中的类

使用import语句导入包

  • eg:专门组织管理和操作数组相关的类
import java.util.Arrays

包是对类、接口等的封装机制的体现,是一种对类或者接口等的很好的组织方式。包还有一个重要的作用:在同一个工程中允许存在相同名称的类,只要处在不同的包中即可。

例如,Date类既存在于java.util包中,也存在于java.sql包中

import java.util.Date;
import java.sql.Date;

如果需要使用java.util中的其他类,可以使用通配符*

import java.util.*

(只要是util底下的所有类,都能够进行适配)

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

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都匹配

在这种情况下需要使用完整的类名

java.util.Date date = new java.util.Date();
  • 使用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 redult = sqrt( pow(x,2) + pow(y,2) );
          System.out.println(result);
    }
}

*归根结底,包就是个文件夹,里面有很多类,类中有很多方法...

自定义包

基本规则

  • 在文件的最上方加上一个package语句指定该代码在哪个包中.
  • 包名需要尽量指定成唯一的名字,通常会用公司的域名的颠倒形式(eg: com.baidu.www;)
  • 包名要和代码路径相匹配。eg:创建com.baidu.demo1的包,那么会存在一个对应的路径        com/baidu/demo1来存储代码
  • 如果一个类没有package语句,则该类被放到一个默认包中.

操作步骤

1.先创建一个包:右键src --> 新建 --> 包 

2.在弹出的对话框中输入包名(小写

3.在包中创建类:右键包名 --> 新建 --> 类,然后输入类名即可

4.此时可以看到磁盘上的目录结构已经被IDEA自动创建出来了

5.同时可以看到,在新创建的Test.java文件的最上方,就出现了一个package语句

static成员

概念

使用学生类实例化三个对象s1、s2、s3,每个对象都有自己特有的姓名、性别、年龄、学分绩点等成员信息,这些信息就是对不同学生进行描述的。

  • 如下所示:
public class Student{

      public static void main(String[] args){
           Student s1 = new Student("李雷","男",18,3.8);
           Student s2 = new Student("韩梅梅","女",19,4.0);
           Student s3 = new Student("Jim","男",18,2.6);
      }
}

假设三个同学是同一班的,那么他们上课肯定是在同一个教室,既然在同一个教室,能否在类中再加一个成员变量,来保存同学上课时的教室呢?!

答案是不行的 --> 在Student类中定义的成员变量每个对象都会包含一份(称为实例变量),因为需要使用这些信息来描述具体的学生。而现在要表示上课的教室,这个教室的属性并不需要每个学生对象中都存储一份,而是需要让所有的学生来共享

在JAVA中,被static修饰的成员,称之为静态成员,也可以称为类成员,其不属于某个具体的对象,是所有对象所共享的。

static修饰成员变量

static修饰的成员变量,称为静态成员变量

[静态成员变量特性]:

  • ①.不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中(最大特性,即静态成员变量不属于对象)
  • ②.既可以通过对象访问(会出现警告),也可以通过类名访问(推荐)
  • ③.类变量存储在方法区当中
  • ④.生命周期伴随类的一生(随类的加载而创建,随类的卸载而销毁)
public class Student{
      public static String classRoom = "101";
      
      public static void main(String[] args){
            //静态成员变量可以直接通过类名访问
            System.out.println(Student.classRoom);
      }
}

static修饰成员方法

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

public class Student{
      private static String classRoom = "101";
}

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 = "101";

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

[静态方法特性]:

①.不属于某个具体的对象,是类方法

② .可以通过对象调用,也可以通过类名.静态方法名(...)方式调用(更推荐)

③.不能在静态方法中访问任何非静态成员变量

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

  • eg:
public static void func(){
     System.out.println("静态的!");
     System.out.println(this.name + "。。。");   //error
}

-->name的调用需要对象的引用来调用,而func()这个静态方法直接通过类名就能调用,不依赖于对象

--> 因此,在静态方法中,不能调用非静态的成员变量或者非静态的成员方法;静态方法当中不包含this

static成员变量初始化

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

Ⅰ.就地初始化

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

public class Student{
      private String name;
      private String gender;
      //...
      private static String classRoom = "101";
}

Ⅱ.静态代码块初始化

什么是代码块?!!

代码块概念及分类

使用{}定义的一段代码称为代码块,可分为以下四种:普通代码块、*构造块、*静态块、同步代码块

普通代码块

定义在方法中的代码块(很少见)

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

构造代码块

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

构造代码块

  • 一般用于初始化实例成员变量
public class Student{
     //实例成员变量
     private String name;
     private String gender;
 
     {
       this.name = "小明";
       this.gender = "男";
     }
   
     public void show(){
          System.out.println("name:" + name + "gender:" + gender);
     }
}
public class Main{
     public static void main(String[] args){
          Student stu = new Student();
          stu.show();
     }
}
//name:小明gender:男

注:构造(实例)代码块只有在创建对象时才会执行 

静态代码块

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

public class Student{
      private static String classRoom;

      static{
           classRoom = "101";
      }
}

注:

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

同步代码块

具体介绍在后续多线程部分...

总结

①.执行顺序:静态代码块 --> 构造代码块 --> 对应的构造方法 

②.静态代码块只执行一次

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Springboot整合SpringSecurity实现登录认证和鉴权全过程

    Springboot整合SpringSecurity实现登录认证和鉴权全过程

    这篇文章主要介绍了Springboot整合SpringSecurity实现登录认证和鉴权全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • 使用mybatis log plugin插件展示出数据库查询语句方式

    使用mybatis log plugin插件展示出数据库查询语句方式

    本文介绍了如何安装和配置MyBatis日志插件,包括集成log4j、配置log4j.xml文件和在application.properties中添加数据库打印配置,通过这些步骤,可以在调试时查看预编译的数据库语句和实际查询语句
    2024-11-11
  • 一篇文中细看Java多线程的创建方式

    一篇文中细看Java多线程的创建方式

    随着计算机的配置越来越高,我们需要将进程进一步优化,细分为线程,充分提高图形化界面的多线程的开发,这篇文章主要给大家介绍了如何通过一篇文中细看Java多线程的创建方式,需要的朋友可以参考下
    2021-07-07
  • java实现List中对象排序的方法

    java实现List中对象排序的方法

    这篇文章主要介绍了java实现List中对象排序的方法,涉及Java中的遍历与对象操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-11-11
  • Spring Boot Mail QQ企业邮箱无法连接解决方案

    Spring Boot Mail QQ企业邮箱无法连接解决方案

    这篇文章主要介绍了Spring Boot Mail QQ企业邮箱无法连接解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • Spring中的循环依赖问题分析(概念、原因与解决方案)

    Spring中的循环依赖问题分析(概念、原因与解决方案)

    循环依赖是一个常见但复杂的问题,尤其对于新手开发者来说,本文将详细介绍循环依赖的定义、成因、Spring的处理方式及解决策略,并通过示例代码帮助读者更好地理解这一概念,感兴趣的朋友一起看看吧
    2025-07-07
  • Java获取用户IP属地模拟抖音详解

    Java获取用户IP属地模拟抖音详解

    细心的小伙伴可能会发现,抖音新上线了 IP 属地的功能,小伙伴在发表动态、发表评论以及聊天的时候,都会显示自己的 IP 属地信息,本篇文章我们来模拟实现这一功能
    2022-07-07
  • springboot引入druid解析sql的过程

    springboot引入druid解析sql的过程

    在开发中,有时我们可能会需要获取SQL中的表名,那么因为不同的数据源类型SQL会存在部分差异,那么我们就可以使用alibaba 的druid包实现不同的数据源类型的sql解析,需要的朋友可以参考下
    2023-08-08
  • Java中不得不知的Collection接口与Iterator迭代器

    Java中不得不知的Collection接口与Iterator迭代器

    这篇文章主要介绍了Java中的Collection接口与Iterator迭代器,文中有详细的代码示例供大家参考,对我们的学习或工作有一定的帮助,需要的朋友可以参考下
    2023-06-06
  • SpringMVC使用MultipartFile实现文件上传

    SpringMVC使用MultipartFile实现文件上传

    这篇文章主要为大家详细介绍了SpringMVC使用MultipartFile实现文件上传功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-04-04

最新评论