首页 > 其他分享 >封装

封装

时间:2024-08-01 10:55:41浏览次数:7  
标签:封装 变量 静态 访问 实例 方法 public

封装

1. 何为封装

当我们需要安全地访问对象时,例如限制给对象赋值的范围(避免数据类型的不同或者数据范围超出预计),我们就需要使用封装技术。
封装就是将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法(getter和setter)来实现对隐藏信息的操作和访问。

2. 访问修饰符

图表:

private关键字

1.为什么要使用private
出于 安全性考虑,我们在写字段时,尽量考虑采用 封装,这样可以隐藏类的细节,只对外开放接口即可实现对象之间的交互。

2.private关键字的定义
private是 一个访问限定修饰符

可修饰的的范围:

修饰成员变量:
表示当前成员变量只能在当前类中使用

修饰成员方法:

表示当前成员方法只能在当前类中使用

public 关键字

1.什么是public关键字?
在Java中,public是一个访问修饰符(Access Modifier),用于控制类、方法、字段等元素的可见性。使用public关键字修饰的元素可以在任何地方被访问,即具有最大的访问权限。

  1. public关键字的使用
    2.1 类的访问权限
    使用public关键字修饰的类可以被任何其他类访问,无论这些类是否在同一个包中。这使得public类成为其他类重用和扩展的基础。

2.2 方法的访问权限
使用public关键字修饰的方法可以在任何地方调用,无论调用者是否与该方法所在类在同一个包中。这样的方法通常是提供给外部调用的接口。

2.3 字段的访问权限
使用public关键字修饰的字段可以在任何地方访问和修改,无论访问者是否与该字段所在类在同一个包中。然而,直接暴露字段并不是一种良好的编程实践,应该使用封装来保护字段的访问。

3. Getter 访问器和 Setter修改器

Getter方法(也称为访问器)用于获取对象的属性值。它通常是一个公共的非静态方法,不接受任何参数,并返回属性的值。Getter方法的命名常以"get"开头,后面跟着属性的名称。例如,如果有一个名为"age"的属性,对应的Getter方法命名为"getAge"。

Setter方法(也称为修改器)用于修改对象的属性值。它通常是一个公共的非静态方法,接受一个参数,并用参数的值来更新属性的值。Setter方法的命名常以"set"开头,后面跟着属性的名称。例如,如果有一个名为"age"的属性,对应的Setter方法命名为"setAge"。

getter方法和setter方法作用:

Getter和Setter方法的使用可以有效地控制对对象属性的访问和修改,提供了封装性和安全性。

1.通过Getter方法,其他类可以获取属性的值而不需要直接访问属性;

2.通过Setter方法,其他类可以修改属性的值而不需要直接修改属性。

这样可以控制属性的访问权限,进行必要的验证和操作。

Getter和Setter方法的好处:

封装性:通过Getter和Setter方法,可以对属性的访问和修改进行控制。
验证和操作:可以在Getter和Setter方法中实现对属性的验证和操作,例如范围检查、格式转换等,确保数据的合法性。
可读性和可维护性:通过Getter和Setter方法可以提供更具描述性和可读性的代码,使代码更易于理解和维护。

Getter方法和Setter方法的主要区别:

访问级别:通常情况下,类的属性被声明为私有,以实现封装的概念,即防止外部直接访问和修改属性。为了让外部代码能够安全地访问和修改属性的值,在类中定义getter和setter方法。这样,外部代码就可以通过调用这些方法来获取和设置属性的值,而不需要直接访问属性本身。
方法命名:getter方法通常以get开头,后面跟着属性名,属性名的第一个字母大写。setter方法通常以set开头,后面跟着属性名,属性名的第一个字母大写。
参数:setter方法需要一个参数,用于设置属性的值。getter方法不需要参数。
返回值:getter方法需要返回属性的值,而setter方法不需要返回

总结

Getter和Setter方法是用于访问和修改对象属性的常用方法,它们提供了封装性,检验和操作的功能,通过规范的命名和方法签名,可以提高代码的可读性和维护性。在面向对象编程中,推荐使用Getter和Setter方法来操作对象的属性

4. this关键字

this的本质就是“创建好的对象的地址”! 由于在构造方法调用前,对象已经创建。因此,在构造方法中也可以使用this代表“当前对象” 。

1.当成员变量和局部变量重名时,使用this

当成员变量和局部变量重名时,在方法中使用this时,表示的是该方法所在类中的成员变量。(this是当前对象自己)

public class Hello {
    String s = "Hello";

public Hello(String s){
    System.out.println("s = "+s);
    System.out.println("1 > this.s = "+this.s);
    this.s = s;//把参数值赋给成员变量,成员变量的值改变
    System.out.println("2 > this.s = "+this.s);
}

public static void main(String[] args) {
    Hello s = new Hello("HelloWorld");
    System.out.println("s="+s.s);//验证成员变量值的改变
}

}

2.把自己当作参数传递

把自己当作参数传递时,也可以用this.(this作当前参数进行传递)

public class A {

public A(){
    new B(this).print();//调用B的方法
}

public void print() {
    System.out.println("HelloAA from A!");
}

}

public class B {
    A a;
    public B(A a){
        this.a = a;
    }
    public void print(){
        a.print();//调用A的方法
        System.out.println("HelloAB from B!");
    }
}

class Test{
    public static void main(String[] args) {
        A aaa = new A();
        aaa.print();
        System.out.println("-------------------");
        B bbb = new B(aaa);
        bbb.print();
    }
}

3.匿名内部类中使用this

有时候,我们会用到一些内部类和匿名类,如事件处理。当在匿名类中用this时,这个this则指的是匿名类或内部类本身。这时如果我们要使用外部类的方法和变量的话,则应该加上外部类的类名。如:

public class Test {
    int i =1;
    public Test(){
        Thread thread = new Thread(){
            public void run(){
                for(int j = 0; j<20; j++){
                    Test.this.run();//调用外部类的方法
                    try {
                        sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        thread.start();
    }

public void run(){
    System.out.println("i="+i);
    i++;
}

public static void main(String[] args) {
    new Test();
}

}

4.this可以调用同一类中别的构造函数

在构造函数中,通过this可以调用同一类中别的构造函数。如:

public class Test {
    public Test(){
        this("this测试成功");
    }
    public Test(String str){
        System.out.println(str);
    }

public static void main(String[] args) {
    Test test = new Test();
}

}
public class Test {
    private String name;
    private int age;

Test(String name){
    this.name = name;
    System.out.println(this.name);
}

Test(String name,int age){
    this(name);
    this.age = age;
    System.out.println(age);
}

public static void main(String[] args) {
    Test test = new Test("我的啊民",22);
}

}

5.this同时传递多个参数

this同时传递多个参数

public class Test {
int x;
int y;

static void showTest(Test test){//实例化对象
    System.out.println(test.x+","+test.y);
}

void seeit(){
    showTest(this);
}

public static void main(String[] args) {
    Test test = new Test();
    test.x = 9;
    test.y = 10;
    test.seeit();
}

}

5. static关键字

  1. 所有的static关键字修饰的都是类相关的,类级别的。
  2. 所有static修饰的,都是采用“类名.”的方式访问。
  3. static修饰的变量:静态变量,修饰的方法是静态方法。

静态变量

静态变量的定义

​ 在 Java 中,静态变量(也称为类变量)是指被声明为 static 关键字的变量,它们属于类而不是实例。静态变量在类加载时被初始化,且所有实例共享同一份静态变量副本。静态变量可以通过类名直接访问,而不需要创建类的实例。

静态变量的定义格式如下:

public class ClassName {
    // 静态变量
    public static dataType variableName;
    

// 静态常量
public static final dataType CONSTANT_NAME = value;

// 静态代码块(用于初始化静态变量)
static {
    // 初始化静态变量
    variableName = value;
}

}

在上面的示例中:

dataType 表示静态变量的数据类型;
variableName 是静态变量的名称;
CONSTANT_NAME 是静态常量的名称,使用 final 关键字修饰;
value 是静态变量或常量的初始值;
静态代码块可以用于对静态变量进行初始化,静态代码块在类加载时执行。
静态变量的访问方式是通过类名直接访问,如 ClassName.variableName。静态变量适合用于表示所有实例共享的数据,如计数器、常量等。需要注意的是,在多线程环境下,对静态变量的访问需要考虑线程安全性。

静态变量的作用

​ java 中的静态变量具有以下几个主要作用:

共享数据:静态变量被所有类的实例所共享,它们存储在方法区中,因此对于所有实例来说,静态变量都只有一份副本。这使得静态变量非常适合用于表示类级别的共享数据,例如全局配置信息、常量等。

方便访问:由于静态变量属于类而不是实例,因此可以通过类名直接访问静态变量,无需创建类的实例。这样可以方便地在代码中使用静态变量,而不必担心实例化对象的问题。

内存管理:静态变量的生命周期与类相同,它们在类加载时被初始化,直到程序结束或类被卸载时才会被销毁。这对于需要长时间存活的数据非常有用,避免了频繁地创建和销毁对象。

常量定义:静态变量还常用于定义常量,通过 final 关键字修饰的静态变量可以作为不可变的常量使用,例如数学常数、配置参数等。

​ 静态变量在 Java 中具有重要的作用,能够方便地表示共享数据、提供全局访问点,并且能够有效地管理内存和定义常量。然而,在使用静态变量时也需注意线程安全性和全局状态管理等问题。

静态方法

静态方法(Static Method)是属于类而不是类的实例的方法。它可以在不创建类的实例的情况下被调用。静态方法通常用于执行与类相关的操作,而不需要访问或修改特定实例的状态。

以下是关于静态方法的声明、调用以及与实例方法的区别:

声明静态方法:

在Java中,声明静态方法需要使用static关键字。静态方法可以直接属于类,而不是类的实例。

public class MyClass {
    public static void myStaticMethod() {
        // 静态方法的代码
    }
}

调用静态方法:

你可以通过类名来调用静态方法,而不需要创建类的实例。

MyClass.myStaticMethod();

静态方法与实例方法的区别:

静态方法与实例方法的区别:

关联性:静态方法与类本身相关,而实例方法与类的实例相关。

调用方式:静态方法通过类名调用,而实例方法需要通过对象实例来调用。

访问权限:静态方法可以访问类的静态成员,但不能访问非静态成员(实例成员)。实例方法可以访问类的静态和非静态成员。

内部引用:静态方法中不能使用this关键字,因为它没有当前对象的引用。实例方法可以使用this来引用当前对象。

生命周期:静态方法在类加载时初始化,而实例方法在对象创建时初始化。

总之,静态方法是与类本身相关的方法,通常用于执行通用操作或访问静态成员。实例方法则是与类的实例相关的方法,可以访问和修改实例的状态。选择使用静态方法还是实例方法取决于你的需求和代码设计。

静态代码块

在Java中,静态代码块(Static Block)是类加载时自动执行的代码块。它属于类,而不是类的任何实例。静态代码块在类被JVM加载到内存时执行,并且只执行一次。无论创建多少个类的实例,静态代码块只会被执行一次。

静态代码块主要用于初始化类的静态变量,或者在类加载时执行一些只需执行一次的操作。

静态代码块的语法如下:

public class MyClass {  
    // 静态变量  
    public static int myStaticVar;  

// 静态代码块  
static {  
    // 初始化静态变量或执行其他操作  
    myStaticVar = 42;  
    System.out.println("静态代码块被执行");  
}  

// 其他成员变量和方法...  

}

静态代码块的特点:

只执行一次:静态代码块在类加载时执行,并且只执行一次。无论创建多少个类的实例,静态代码块都不会再次执行。
先于构造器执行:静态代码块在类的构造器(包括实例构造器和静态构造器)之前执行。
不能访问非静态成员:由于静态代码块属于类,而不是类的实例,因此它不能直接访问类的非静态成员(非静态变量和非静态方法)。

静态代码块与构造器的区别:

静态代码块属于类,构造器属于类的实例。
静态代码块在类加载时执行,构造器在创建类的实例时执行。
静态代码块只执行一次,而构造器每次创建类的实例时都会执行。

静态代码块的使用场景:

初始化静态变量:可以在静态代码块中初始化类的静态变量,确保在类的其他部分使用这些变量时它们已经被正确初始化。
执行只需执行一次的操作:如果有些操作只需要在类加载时执行一次,比如加载配置文件、初始化数据库连接池等,可以将这些操作放在静态代码块中。
多个代码块中有相同的语句时,代码看起来比较冗余,这时我们可以把相同的语句放入到一个代码块中
注意:
需要注意的是,虽然静态代码块在类加载时执行,但并不意味着它在程序启动时立即执行。类加载的时机取决于JVM和类的使用方式。例如,如果一个类从未被使用,那么它的静态代码块可能永远不会被执行。

6. jar

Java中的jar第三方类库是一种将Java类库打包成JAR(‌Java Archive)‌文件的形式,‌以便于分发和使用。‌这种形式允许开发者将编译后的Java类文件、‌相关的元数据和资源文件打包到一个文件中,‌从而方便地在不同的Java应用程序之间共享和重用这些类库。‌JAR文件不仅包含了编译后的.class文件,‌还可能包含一些配置文件、‌文本资源、‌图片等,‌这些资源在运行时可以被Java应用程序访问和使用。‌

JAR文件的使用非常广泛,‌它们是Java应用程序开发中不可或缺的一部分。‌开发者可以通过将自定义的类库打包成JAR文件,‌然后在其他Java项目中使用这些JAR文件,‌从而实现代码的重用和模块化开发。‌此外,‌许多开源项目和第三方库也以JAR文件的形式提供,‌这些库提供了丰富的功能,‌如网络通信、‌数据库访问、‌图形用户界面(‌GUI)‌开发等,‌极大地丰富了Java应用程序的开发手段。‌

标签:封装,变量,静态,访问,实例,方法,public
From: https://www.cnblogs.com/zpjd/p/18336207

相关文章

  • 封装
    封装1.封装的定义在Java中,封装(Encapsulation)是面向对象编程(OOP)的四大基本特性之一(其他三个是继承、多态和抽象)。封装是一种将对象的属性(成员变量)和方法(成员函数)结合在一起,并隐藏对象的属性和实现细节,仅对外公开接口(即方法)来与对象进行交互的机制。封装的目的主要有两个:保护内......
  • 关于使用C#注入C++的封装DLL后打印内容乱码
    最近因需要,用C++写了个钩子的DLL,一切工作测试通过后,放到C#里使用P/Invoke调用,发现部分乱码,最后反复测试,才发现一个问题,原来SetWindowsHookEx这个函数,也是分A版和W版,最后换了就正常了,附上对比。。乱码[DllImport("user32.dll",SetLastError=true]publicstaticex......
  • 封装Vue 的 SVG 组件
    svg静态资源在assets下新建一个svg文件夹,用于存放svg图片svgIcon组件在components下新建一个文件夹,包含两个文件index.ts和SvgIcon.vuevue.config.jsmain.ts需要引入组件svgIcon使用**.vue<svg-icon iconClass="invite" className="iconicon-invite" /> *......
  • Java中的封装
    在Java中,封装(Encapsulation)是面向对象编程(OOP)的四大特性之一(其他三个是继承、多态和抽象)。封装主要用来隐藏对象的属性和实现细节,仅对外公开接口(方法),与对象交互只能通过这些接口进行。这样做的好处包括提高代码的安全性、灵活性和可维护性。如何进行简单封装1.使用访问修饰......
  • 使用C99 变长数组和和零长数组特性封装协议回复消息
    背景:主从机交互协议中,需要针对不同控制字封装回复消息接口。本文使用变长数组特性和零长数组特性对这类接口进行统一封装。 1#pragmapack(1)2typedefstruct{3uint8_tmagic;4uint8_tlen_H;5uint8_tlen_L;6uint8_tcmd;7uint8_t......
  • vue3 封装request请求
    vue3原生请求封装我这里用一个案例来解释需求:把vue3原生的静态页集成到vue2的若依项目并且可以访问vue2接口在vue3src下的utils下创建文件request.ts文件importaxiosfrom"axios";import{showMessage}from"./status";//引入状态码import{ElMess......
  • SqlSugar 多数据源的简单封装
    参考SqlSugar的官网文档,我自己封装了一个支持多数据库的UnitOfWork的SqlSugar封装类,直接使用SqlSugar的仓储操作如下:///<summary>///数据库实例基类///</summary>publicabstractclassBaseDbClient{///<summary>///获取数据库客户端实例......
  • 面向对象编程(2)——封装
    目录一、概念1.1主要特点1.2实例二、封装的内容2.1 属性(数据成员)2.2 方法(成员函数)2.3 实现细节2.4 类的依赖关系2.5示例2.5.1示例2.5.2解释三、原则与注意事项3.1 封装的原则3.2注意事项一、概念        封装(Encapsulation)是面向对象编程......
  • yii2代码封装
    1、批量更新某个字段/***@throwsCDbException*@throwsCException*updatexxxTablesetcolumn1=casepk*whenwhenData1thencaseData1*...*END*whereidin(1,2,3...)*/publicfunctionbatc......
  • 使用vite创建react项目并进行初始化(仓库、路由、封装)
    前言学的时候都是跟着教程进行创建,后面发现自己写项目的时候记不住需要做什么,所以现在写一篇来给自己总结一下。(后面忘了也不用翻视频了,直接照着抄答案)只写流程,没有理论。这是我写的习惯,只具备一定通用性,有需要可参考。创建项目npmcreatevite@latestHireSpherenpmins......