前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Java面向对象三大特征——封装】

【Java面向对象三大特征——封装】

作者头像
用户10920432
发布2024-10-24 08:03:52
1000
发布2024-10-24 08:03:52
举报
文章被收录于专栏:Python数据结构与算法

数据类型类别

类型

位大小

默认值

基本数据类型

描述

描述

描述

整型

byte

8位

0

整型

short

16位

0

整型

int

32位

0

整型

long

64位

0

浮点型

float

32位

0.0

浮点型

double

64位

0.0

字符型

char

16位

‘\u0000’

布尔型

boolean

-

false

引用数据类型

描述

描述

描述

class

-

null

接口

interface

-

null

数组

array

-

null

枚举

enum

-

null

注解

annotation

-

null


面向对象三大特征

封装Encapsulation

封装:不仅仅是将public变成private,而是通过将类的属性和实现细节隐藏起来,只暴露必要的部分(对外只提供一些开放的接口)。这可通过设置属性为private,protected来实现,防止外部直接修改或访问对象的状态(属性)。

封装的核心理念:隐藏内部实现细节,提控制访问的方式。通过类内提供的public的访问方法(如gettersetter)或其他操作方法,来安全的访问或修改内部属性。这确保了对象的状态只能通过特定的方法改变,从而提高数据的安全性和代码的可维护性。

通过private类修饰的方法或属性只能在当前类内进行调用。

代码语言:javascript
复制
package com.javastudy.demo;
import java.util.*; //*表示通配符,只要所用的东西都在util文件夹下,它都能帮你找到

class Student{
//    --> 通过private进行封装
    private String name;
    public  int age;

    //通过公开方法修改成员变量
    public void setName(String name) {
        this.name = name;
    }
    //通过公开方法获取修改后的成员变量
    public String getName(){
        return  this.name;
    }

    //构造方法的创建
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //普通方法的创建
    public void eat(){
        System.out.println(this.name+ " 正在吃饭!");
    }
}

public class Test {
    public static void main(String[] args) {
        Student student1 = new Student("Aileen",21);
        student1.eat();
        student1.setName("Ling");
        System.out.println(student1.getName());
        student1.eat();
    }
}
运行结果:

通过上面运行结果可知,在创建对象student1的时候我们给它的属性赋值为“Aileen”和21,当我通过调用公开set设置完成员变量以后,“Aileen”就变成了“Ling”,并且通过调用公开的eat方法,我们也可以知道,变量名发生考虑了改变,于是我们可以得出以下结论:封装了的属性可以间接通过公开的set方法在类外来进行修改,并且可以通过在类内设置get方法来回获取修改后的属性,类外进行相应的get方法的调用即可。

实用tips:

当我们有很多属性要实现封装并对其进行修改和调用的时候,我们可以通过点击鼠标右键或者fn+alt+insert点击Generate这个选项,就会弹出get and set方法的批量设置,我们选中我们要修改的变量即可生成对应字段(成员变量)的get and set方法。

Java当中包就是文件夹,同一个包同一个类就是如下图所示:

同一个包不同类,如下所示:

包访问权限

在Java中,包访问权限(也称为默认访问权限或者包私有权限)是一种没有明确指定访问修饰符(如 public, private, 或 protected)的成员(包括类、接口、变量和方法)的访问级别。这种权限也被称作“默认访问级别”。

具体来说,当一个类成员没有被任何访问修饰符修饰时,它拥有包访问权限。这意味着只有同一个包内的其他类可以访问这些成员。不在此包中的类无法访问这些成员,即使是这些类的子类也不行。

  • 包访问权限的特点如下:
    • 局限于同一包内:只有同一个包内的类可以访问没有访问修饰符的成员。
    • 不影响类的继承:即使一个类继承了具有包访问权限的另一个类,如果这两个类不在同一个包中,子类也无法访问父类的包访问权限成员。
    • 适用于类、接口、变量和方法:这种访问级别可以用于类、接口及其成员变量和方法。

同一个包不同类调用,输出结果为99.

同一个包同一个类调用,输出结果也是99。

不同访问修饰符在Java中的访问权限

访问修饰符

同一包中的同类

同一包中的不同类

不同包中的子类

不同包中的非子类

private

default (no modifier)

protected

public


static成员

static修饰成员变量

被static修饰的成员变量不属于对象属于类,相当于公共的东西它不依赖于对象,只能通过它所属的类来访问,虽然通过对象访问没有报错,但是不合理。

代码语言:javascript
复制
package com.javastudy.demo;
import java.util.*; //*表示通配符,只要所用的东西都在util文件夹下,它都能帮你找到
import static java.lang.Math.pow;

class Student{
//    --> 通过private进行封装
    private String name;
    private   int age;

    private  String classroom;

    public String getClassroom() {
        return classroom;
    }

    public void setClassroom(String classroom) {
        this.classroom = classroom;
    }


public class Test {

    public static void main(String[] args) {
        Student student1 = new Student("Terry",10);
        student1.setClassroom("A-101");
        //----------------------------------------------------------------------
        Student student2 = new Student("kendrid",11);
        student2.setClassroom("A-101");
        //----------------------------------------------------------------------
        Student student3 = new Student("Mike",12);
        student3.setClassroom("A-101");
        //----------------------------------------------------------------------
        System.out.println(" ");
    }

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

  • 这种方法不现实,因为在Student这个类中定义的成员变量,每个对象都会包含一份(即实例变量),因为需要使用这些信息来描述具体的学生。现在要表示学生上课的教室,这个教室的属性并不需要每个学生对象中都存储一份,而是需要让所有的学生来共享。
  • 在Java中,被static修饰的成员,称为静态成员,也可称为类成员,其不属于某个具体的对象,是所有对象共享的
  • 静态的成员变量随着类被加而创建,随着类被销毁而销毁
  • ⚠️此外注意,静态的只能是成员变量,即在类内方法外的变量,static不能修饰局部变量。

static修饰方法

我们根据上面的运行结果可以看出name这个属性的访问是需要对象的,而我们用static修饰的这个方法是不能够用对象去访问的,这就会导致在使用的时候报错,因为静态方法的内部不能使用非静态的数据成员,非静态方法有this参数,在静态方法调用时候无法传递this引用,但非静态方法里面可以调用静态的东西。

通过上面的运行结果我们可以得出以下结论:非静态方法的调用,如eat是通过创建的对象student1去进行访问的,在eat这个非静态方法里面我们调用了静态方法sleep,静态方法可以通过类名进行调用

⚠️虽然静态成员变量通过对象去访问不合理,但是我们还是能用的,如上代码所示,我们①-③通过创建的对象去修改了静态的成员变量,让他每次加1,在第四个我们通过类名去调用它的成员变量并让他减1,得到最终答案为102。


静态初始化的方法
  • 1.直接赋值进行初始化。
  • 2.通过静态代码块进行初始化

代码块{}

使用{}定义的一段代码称为代码块。

普通代码块
构造代码块

用来初始化非静态的数据成员(也可以初始化静态)

静态代码块

用来初始化静态成员变量

  • 从上面的运行结果我们可以对比得出以下结论:
    • 静态代码块在类加载时执行,所以无论是否创建对象,只要类被加载,静态代码块就会先执行,并且只执行一次。
    • 实例代码块在每次创建对象时执行,所以当创建第一个对象时,实例代码块和构造方法都会执行。当创建第二个对象时,实例代码块和构造方法再次执行。
    • 即使没有调用静态代码块里面的内容(比如静态变量或静态方法),静态代码块依然会在类加载时执行。

特性

静态代码块

普通代码块

实例代码块

关键字

static{}

无特殊关键字

{} 包裹,无 static 关键字

执行时机

类加载时执行,只执行一次

每次调用方法或逻辑块时执行

每次创建对象时执行

执行顺序

在类的任何静态成员前执行

根据调用逻辑执行

在构造方法之前执行

用途

类级别的初始化,初始化静态变量

方法或代码块级别的逻辑处理

实例级别的初始化

是否依赖对象

不依赖对象,只依赖类的加载

与对象无关,和方法逻辑有关

依赖对象,每个对象创建时执行

是否可以访问实例变量

不能直接访问实例变量,只能访问静态变量

可以访问方法范围内的变量

可以访问实例变量和静态变量

执行次数

只执行一次

由方法调用次数决定

每创建一个对象执行一次

典型用途

初始化静态变量、注册驱动等

在方法内部处理逻辑

初始化实例变量

根据上面的代码我们可知,一个类中可以包含多个静态代码块,在编译代码时,编译会根据定义的先后顺序依次执行(就是把多个静态代码块合并成一个),如下图所示:

通过上面的运行结果我们可知:我们可以通过创建对象然后调用get方法和set方法来直接给我们封装好的属性来赋值,并通过对象来访问对应的成员方法,而对于静态HaveFun方法我们则通过类名进行访问。

我们也可以通过再创建一个Dog的无参构造方法来进行属性的赋值

然后我们通过创建Dog的对象来调用show方法将所有的属性值打印出来,如下图所示:


toString()

为什么打印对象的结果会是这样子呢?

通过对比我们两段代码的打印结果,我们可以得出以下结论:当我们调用Java内部的重写方法toString()方法的时候,对象的属性就能完完整整的打印出来,而当我们没有调用这个重写方法的时候,打印出的是这个类对应的路径和它的对象的哈希值的组合。下面让我们来介绍一下Java当中,这个toString方法的相关知识吧,加深对它的理解~

toString:是Java中一个非常重要的方法,他定义在java.lang.Object类中,这意味着所有的Java类都继承了这个方法。toString()方法的主要作用是返回一个代表对象值的String,通常包括类的名称和对象的属性信息。

    • toString() 方法的作用:
  • 提供对象的字符串表示:这是最直接的作用,它允许开发者获取对象的字符串表示形式,便于调试和显示。
  • 调试和日志记录:在调试程序或记录日志时,经常需要将对象转换为字符串形式以便查看其状态。
  • 数据展示:在用户界面显示对象信息时,通常需要将对象转换为易于阅读的字符串形式。
  • 网络传输:在网络通信中,对象通常需要被序列化为字符串形式进行传输。

toString()方法的主要功能就是提供更有意义的表示对象,使得打印和显示对象时能够看到对象的属性和状态,如果不重写,将只能提供一个不太有用的默认字符串表示,因此在开发中,通常会为自定义的类重写toString()方法,以便于调试和数据展示。



通过重写我们可以将对应的属性值打印出来


因为static修饰的是类变量,类变量是公共的,只能通过类去访问,而不能通过对象去访问,所以编译会发生报错。如果没有static修饰,当j调用这个方法的时候,就会打印出1。

在Java中我们不能import导入指定的包,我们只能导入指定的类或者是通配符,如第二行import语句那样会导致报错。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-10-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 面向对象三大特征
    • 封装Encapsulation
      • 运行结果:
      • 实用tips:
      • 包访问权限
        • 不同访问修饰符在Java中的访问权限
          • static成员
            • static修饰成员变量
            • static修饰方法
            • 静态初始化的方法
          • 代码块{}
            • 普通代码块
            • 构造代码块
            • 静态代码块
          • toString()
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档