前言:在面向对象的编程语言中,有三个特性:封装,继承,多态

(一).封装

1.概念

简单的来说,成员变量不能在类外直接使用,但是可以通过其他方法去用变量

比如,我们用的电脑,实际上电脑已经被封装好了的,电脑里面的CPU,显卡等,我们统统都是看不到的,我们只关心如何去使用电脑即可。     

那么在Java中,我们如何进行封装呢?

首先我们现在看一下什么是访问修饰限定符

2.访问修饰限定符

四者的区别:

public:谁都能使用

private:只有同一个包同一个类中才能使用

default:只要是同一个包中就可以使用

在Java中,我们通常会把类当中的成员设置为private,设想一下,如果我们类中设置了username和password两个成员变量,那么我们肯定是不希望别人能看到的,那么我们就可以讲username和password设置为private,这样,我们的username和password就只能在类当中去访问了,一旦出了类,我们就访问不了

通过图片可以看到,我先把username设置成了public,那么我们在类外是可以使用username的。

但是我将password设置成了private,我们可以看到,我们是拿不到password的

那么我现在就是想访问我的password,怎么办?

我们可以通过set和get方法,来访问我的password

public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

通过提供set和get方法,我们就可以在类外访问我们的password成员变量了

class User{
    public String username;
    private String password;

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}
public class Main {
    public static void main(String[] args) {
	User user=new User();
    user.username="zhangsan";
    user.setPassword("123");
    System.out.println(user.getPassword());
    }
}

通过打印,我们可以看到,我们成功访问到了我们的password属性

当然,我们可以通过编辑器来快速导入我们的set和get方法

首先右击鼠标

通过图片上的内容,我们就可以通过编辑器,快速生成我们的get和set方法了

(二).包

在日常生活中,我们通常会用文件夹来放不同类型的文件,每一个大文件夹中包含着多个小文件夹。换成Java的角度,那么每个大文件夹就可以理解为包,多个小文件夹就可以理解为多个类

包是对类和接口等的封装机制的体现,是一种对类或接口等的很好的组织形式

常见的Java包有:

1.java.lang:常用的基础类(String、Object)

2.java.util:java提供的工具程序包
 

当我们想要打印数组中的内容是,我要需要调用Arrays.toString()这个方法来讲数组转为字符串

import java.util.Arrays;

public class Main {

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

当我们使用toString()这个方法的时候,我们就需要导入一个java.util这个包,同时我们要说明这个包底下的Arrays这个类

导入包中的类的三种方式

1.直接使用

包名.类名.方法

public class Main {

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

缺点:每次使用Arrays.toString这个方法都需要写java.util.Arrays.toString(),所以会比较麻烦,一般不使用

2.通过import语句来导入包种的类

格式 :import  包名.类名;

举例:import java.util.Arrays;

import java.util.Arrays;

public class Main {

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

3.导入包中所有的类

import java.util.*;

缺点:不知道具体使用了哪个类,如果当两个不同的包中有相同的类,那么编辑器就不知道具体是使用的哪个类了

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

}
public class Main {

    public static void main(String[] args) {
        Date date=new Date();
    }
}

通过图片中可以看出,程序报错了,这就是因为,util包中也都Date类,sql包中也有Date类,当同时导入的时候,编辑器就不知道是哪个类了。

自定义包

右键src

通过上述操作,我们就可以创建一个包了

(三).关键字static

我们先通过一个例子来引入static关键字

class Studnet{
    public String name;
    public int age;
    public String classNum;

    public Studnet(String name, int age, String classNum) {
        this.name = name;
        this.age = age;
        this.classNum = classNum;
    }


}
public class test {
    public static void main(String[] args) {
        Studnet studnet1=new Studnet("张三",20,"1班");
        Studnet studnet2=new Studnet("李四",22,"1班");
        Studnet studnet3=new Studnet("王五",36,"1班");
    }
}

我们创建了一个Student类,并实例化了三个对象,分别是students1,students2,students3

调试起来看,他们都是有classNum这个属性,属性值也一样

那么这时候,我们就可以将这个属性设置为公用的属性,如何设置呢?

通过static关键字

通过图片来看,classNum属性没有了。

那是因为,一旦成员变量被staitc修饰了,那么被static修饰的成员属性不再依赖于对象,简单的来说,这个classNum属性不属于对象了,这个classNum只有一份,存放在了方法区中

那么,如果我想访问这个classNum成员属性,应该如何访问?

答:可以通过类名进行访问,即类名.静态成员变量

静态的不依赖于对象,意味着不需要对象的引用来访问

静态成员变量的初始化方法:

1.就地初始化

2.可以通过set和get方法进行初始化

3.可以通过构造方法进行初始化

同时我们也要注意使用static的注意事项下·

1.static方法中不能使用this关键字

其实这一点也好想,static不依赖于对象,调用的时候直接通过类来调用,而this必须依赖于创建的对象才能存在,所以二者在定义的时候就会发生冲突。

2.在静态方法中不能使用非静态方法

如果想要在静态方法中访问非静态的方法,只能通过类来实例化一个对象,通过对象的引用来调用非静态的方法。

3.在非静态方法中可以直接调用静态方法

总结:

方法或者成员变量的调用就2种情况:

(1).通过类名进行调用

(2).通过对象的引用进行调用

(四).代码块

1.概念

使用{}定义的一段代码就叫代码块。

2.分类

代码块分为普通代码块,静态代码块,构造代码块,同步代码块(多线程会深入)

3.普通代码块

普通代码块定义在方法中

        

我在{}种写了

int a=10;
System.out.println(a);

那么a的作用域就在{}种,一旦出了{},那么a就销毁了,所以当出了{}后,我再打印a,就会报错        

4.构造代码块

定义在类中的代码块,也叫实例代码块。一般用于初始化实例成员变量。

快速创建构造代码块的方法

5.静态代码块

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

为什么说静态代码块一般用于静态成员变量的初始化?

因为静态代码块在类加载的时候就会被执行。也就是说,当程序跑起来的时候,首先执行的就是静态代码块。

如果出现多个静态代码块,都是静态的情况下,和定义的顺序有关。

class Studnet{
    public String name;
    public int age;
    public static String classNum;

    static {
        System.out.println("静态代码块1");
    }
    static {
        System.out.println("静态代码块2");
    }


    public Studnet(String name, int age) {
        this.name = name;
        this.age = age;
//        System.out.println("构造代码块");
    }
}
public class test {

    public static void main(String[] args) {
        Studnet studnet=new Studnet("张三",20);
    }
    public static void main1(String[] args) {

    }
}

class Studnet{
    public String name;
    public int age;
    public static String classNum;

    static {
        System.out.println("静态代码块2");
    }
    static {
        System.out.println("静态代码块1");
    }



    public Studnet(String name, int age) {
        this.name = name;
        this.age = age;
//        System.out.println("构造代码块");
    }
}
public class test {

    public static void main(String[] args) {
        Studnet studnet=new Studnet("张三",20);
    }
    public static void main1(String[] args) {

    }
}

通过上面两个代码可以看出,当静态代码块2定义在静态代码块1前面的时候,就会先打印静态代码块2,所以有多个静态代码块的时候,会按照定义的顺序来执行。

6.静态代码块,实例代码块,构造代码块执行的先后顺序

class Studnet{
    public String name;
    public int age;
    public static String classNum;

    public Studnet(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("构造代码块");
    }
    {
        System.out.println("实例代码块");
    }

    static {
        System.out.println("静态代码块");
    }
}
public class test {

    public static void main(String[] args) {
        Studnet studnet=new Studnet("张三",20);
    }
}

通过代码的运行结果我们可以看出,先执行的是静态代码块,然后是实例代码块,最后是构造代码块

让我们实例化多个对象看看

class Studnet{
    public String name;
    public int age;
    public static String classNum;

    public Studnet(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("构造代码块");
    }
    {
        System.out.println("实例代码块");
    }

    static {
        System.out.println("静态代码块");
    }
}
public class test {

    public static void main(String[] args) {
        Studnet studnet=new Studnet("张三",20);
        System.out.println("=========");
        Studnet studnet1=new Studnet("李四",55);
    }
}

当我们实例了多个对象之后,我们会发现,“静态代码块”就打印了一次,说明静态代码块就执行了一次,也就是说,这个类就加载了一次。[知识点]双亲委派模型

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐