JavaSE-No.6.2——封装与static

JavaSE传送门

JavaSE_Start

JavaSE-No.5——Java数组的定义与使用

JavaSE-No.6.1——Java的类和对象


目录

  • 1. 封装
    • 1.1 概念
    • 1.2 访问限定符
    • 1.3 封装的拓展之包
      • 1.3.1 包的概念
      • 1.3.2 自定义包
      • 1.3.3 系统的包
      • 1.3.4 常用的包
  • 2. static成员
    • 2.1 static修饰成员变量
    • 2.2 static修饰成员方法
    • 2.3 static成员变量初始化


1. 封装

1.1 概念

面向对象程序三大特性:封装、继承、多态。何为封装呢?简单来说就是套壳屏蔽细节

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

比如:说我们平常使用手机,我们只需要知道,如何开机,如何使用。并不关心手机内部的核心部件,不需要知道主板的线路布局,不需要知道CPU是如何设计的。厂商在出厂时,在外部套上壳,将内部隐藏起来,让用户可以与手机交互即可。

1.2 访问限定符

封装的实现需要我们先了解访问修饰限定符

Java中提供了四种访问限定符:

JavaSE-No.6.2——封装与static_第1张图片

#public:在任何地方,都可以访问它修饰的成员或方法,或者类。

#protected:在继承会学到。

#dafault:指默认。在同一个包中进行访问。

例如: 此时的year前面什么都不加,就是默认权限。

JavaSE-No.6.2——封装与static_第2张图片

#private:私有的。只能在当前类中访问。

我们现在建一个Date类:

public class Date {
    public int year;
    public int month;
    public int day;

    public Date() {
        
    }
    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

    public void printDate() {
        System.out.println(year+" "+month+" "+day+" ");
    }

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

我们新建一个类TestDemo,在TestDemo中用Date类,因为是public修饰的,我们可以看到没有报错。year,month,day也都可以访问。

JavaSE-No.6.2——封装与static_第3张图片

这时我们把year改成private修饰,year的访问权限就变小了。只能在当前类中访问。这时我们的TestDemo中报错了,无法访问year

JavaSE-No.6.2——封装与static_第4张图片

此时我们对year进行了封装,类外就不能访问这个被封装的year。

我们来思考一个 问题 ,如果外部想要使用year,应该怎么办呢?

答:这时我们需要对这个year,提供一个公开的接口

public int getYear() {
    return year;
}

public void setYear(int year) {
    this.year = year;
}

这样我们就可以在TeatDemo中使用我们的year。

JavaSE-No.6.2——封装与static_第5张图片

我们每次都手写接口,十分的麻烦,这时我们可以借助idea

JavaSE-No.6.2——封装与static_第6张图片

总结:封装就是对类的实现细节进行隐藏,提供公开的方法,供类的调用者进行使用。

1.3 封装的拓展之包

1.3.1 包的概念

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

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

1.3.2 自定义包

在idea中建包, # 注意 # 包名,规范是小写的。通常会用公司的域名的颠倒形式。

JavaSE-No.6.2——封装与static_第7张图片

这里其实就是建了三个文件夹

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4YSPRV3W-1652255386000)(C:/Users/gu%27jiu/AppData/Roaming/Typora/typora-user-images/image-20220511111426334.png)]

我们在www下建一个类TestDemo,我们可以看到和src下的TestDemo互不影响,且出现了一行代码。

JavaSE-No.6.2——封装与static_第8张图片

1.3.3 系统的包

例如1: 我们这里使用Array.toString,会导一个系统的包,Arrays其实就是人家写好的一个类。

JavaSE-No.6.2——封装与static_第9张图片

Arrays在哪里呢?

JavaSE-No.6.2——封装与static_第10张图片

如果我们不导包,我们应该如何使用toString呢?我们就需要这样做:

public static void main(String[] args) {
        int[] array = {1,2,3,4,5};
        System.out.println(java.util.Arrays.toString(array));
}

我们来思考一个 问题util下面有很多包,如果我们要同时使用多个,我们应该怎么写呢?

import java.util.*;//导入util下所有的包

例如2: 我们创建一个Date类,在utlisql下面都有Date的包,如果我们这样写,是正确的吗?

JavaSE-No.6.2——封装与static_第11张图片

为什么会报错?

站在编译器的角度下,utilsql下都有Date,不知道应该调用哪个Date,我们必须指定他。

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

public class TestDemo {
    public static void main(String[] args) {
        java.util.Date date1 = new java.util.Date();//不会报错
        java.sql.Date date2 = new java.sql.Date(12);
    }
}

静态导入

例如: 使用Math.pow,导入一个静态的包。(我们一般不这么用)

import static java.lang.Math.*;

public class TestDemo {
    public static void main(String[] args) {
        double a = pow(2,2);
    }
}

1.3.4 常用的包

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

  2. java.lang.reflflect:java 反射编程包;

  3. java.net:进行网络编程开发包。

  4. java.sql:进行数据库开发的支持包。

  5. java.util:是java提供的工具程序包。(集合类等) 非常重要

  6. java.io:I/O编程开发包。


2. static成员

我们先建一个学生类,我们已知全部学生都是宝宝班的。

class Student {
    public String name;
    public double score;
    public int age;
    public String classes;//宝宝班

    public Student(String name, double score, int age) {
        this.name = name;
        this.score = score;
        this.age = age;
    }
}

我们来new两个学生。

public class Test {
    public static void main(String[] args) {
        Student student1 = new Student("依古比古", 69.5,18);
        Student student2 = new Student("唔西迪西", 79.0,19);
    }
}

JavaSE-No.6.2——封装与static_第12张图片

我们发现,两个学生是宝宝班的,并且都存了一次。 问题 :我们是否能只存一次呢?

这时我们就要用到static

public String name;
public double score;
public int age;
public static String classes = "宝宝班";//用static修饰

此时我们的classes就不会存到对象里,而是被存到了方法区

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

2.1 static修饰成员变量

这时我们可以把成员变量分为:普通成员变量静态成员变量(static修饰)。

我们继续上面的代码,如果我们现在使用student1去访问classes。使用student1.c并没有classes。

JavaSE-No.6.2——封装与static_第13张图片

但如果我们自己敲上.classes我们看他并没有报错,但我们通常不会这么用。

JavaSE-No.6.2——封装与static_第14张图片

静态成员变量[又叫类变量]:不属于对象。 所以正确的访问方式是通过类名来访问(如上图绿色)。

静态成员变量最大的特性:不属于某个具体的对象,是所有对象所共享的

静态成员变量特性 :

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

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

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

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

此外我们话可以加一个final,且必须初始化。

JavaSE-No.6.2——封装与static_第15张图片

2.2 static修饰成员方法

我们来分别写一个普通的方法和一个静态方法(static修饰)

public void func1() {
    System.out.println("这是一个普通方法");
}
public static void func2() {
    System.out.println("这是一个静态方法 -> 类方法");
}

我们访问静态方法时,也用类名.方法来使用。

Student.func2();

我们来思考一个问题 ,如果我们在static修饰的func2中想使用name,这样写,可以使用吗?

public static void func2() {
        System.out.println("这是一个静态方法 -> 类方法" + name);
}

答:当然不能,name是依赖于对象的引用的。但是func2调用的时候没有生成对象,静态方法不依赖于对象,不能调用name。

我们再看一个问题 ,那我们是否能在func1中使用static修饰的classes

public void func1() {
        System.out.println("这是一个普通方法");
        classes = "花园班";
}

答:可以,因为func1依赖对象,classes不依赖对象,func1依赖的更多。

那么我们可以怎么访问name呢?可访问的方法:

public static void func2() {
        Student student = new Student("依古比古", 69.5,18);
        System.out.println("这是一个静态方法 -> 类方法" + student.name);
}
public static void func2(Student student) {
        System.out.println("这是一个静态方法 -> 类方法" + student.name);
}

静态成员方法特性 :

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

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

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

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

知识小拓展

JavaSE-No.6.2——封装与static_第16张图片

在普通方法中,隐藏着一个this参数,但在静态方法和构造方法中没有。

2.3 static成员变量初始化

# 注意 # 静态成员变量一般不会放在构造方法中来初始化,构造方法中初始化的是与对象相关的实例属性

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

  1. 就地初始化

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

    public String name;
    public double score;
    public int age;
    public static String classes = "宝宝班";
    
  2. 静态代码块初始化

  3. 那什么是代码块呢?下一篇继续~


(( ◞•̀д•́)◞⚔◟(•̀д•́◟ ))

以上就是今天要讲的内容了,希望对大家有所帮助,如果有问题欢迎评论指出,会积极改正!!下一篇文章会继续讲述Java的内部类的相关知识,期待大家支持,谢谢~

你可能感兴趣的:(JavaSE_Start,java,开发语言)