包,封装和static

包是什么?

包(Package)就像我们电脑中的文件夹一样,通过将不同类型的文件放在不同不同的文件中,来达到方便管理和查找的作用.在java中,包的作用就是用来组织各个类,这样不仅方便管理,还能有效防止类名冲突.

包的作用是什么?

如上段话所说.主要作用是方便管理和防止类名冲突.

例如:虽然一个项目中两个不同的程序员都写了一个名为Add类,但是一个放在add1包中,另一个放在add2包中便不会报错

如何使用包?

java中使用包的方法是直接进行导入即可,但导入的包必须先声明

声明包

java中提供了关键字package来进行声明包操作

package demo1; //声明包
public class Add {
    public static int add(int a, int b)
    return a + b;
}
导入包

java中提供了关键字import来进行导入包操作

import demon1.Add; //导入包
public class Test { //类定义不能用static
    public static void main(String[] args){
    int sum = Add.add(1, 2);  //使用包
    System.out.println(sum);
    }
}

另外,还有一种使用包的方式,该方式无需导入,如下

public class Test {
    public static void main(String[] args) {
        int sum = demo1.Add.add(1,2);
        System.out.println(sum);
    }
}
在使用包时会出现的问题

当两个不同的包中有同一个名字的类

import java.util.Date;
import java.sql.Date;
public class aa {
    public static void main(String[] args) {
        Date date = new Date();
    }
}

如果我们试图将这两个类都导入会报错,毕竟IDE也不知道你究竟是用哪个包的类
这个时候,我们可以用显式导入,指定Dete类使用的包,便不会报错

import java.util.Date;
import java.sql.Date;
public class aa {
    public static void main(String[] args) {
        java.util.Date date = new java.util.Date();
    }
}

包使不同方式的优缺点

方式 示例 优点 缺点
导入具体类 import demo1.Add; 明确依赖,可读性好 需逐个导入
导入包下所有类 import demo1.*; 方便,少写代码 可能引入多余类
显式导入 demo1.Add.add(1,2); 无需导入 代码冗长

封装

封装是什么?

封装(Encapsulation)是 Java 面向对象编程的三大特性之一(另外两个是继承和多态),它就像是把东西包装在一个盒子里,只留几个 “接口” 让外部使用,而隐藏内部的具体实现.

假如对于一个空调,它能做的事情只有开关机,制热,制冷.而对于用户来说,用户不需要知道是怎么做到开关机,制冷,制热的.用户只需要知道怎么来让空调开关机,制热,制冷即可.

封装的作用是什么?

  1. 降低代码的耦合性.封装可以降低对象和对象之间的耦合度,当对象内部发生变化时,只需要修改对象内部即可,不会影响到外部程序,因为公开的接口是不会发生改变的
  2. 降低代码的复杂性.封装是隐藏了对象内部的实现细节,只提供了公开的接口给外部,使用起来更加简单
  3. 提高安全性.封装可以隐藏对象的具体实现细节,阻止外部程序直接访问对象的内部状态,从而保护数据不被意外修改或破坏

如何进行封装

class Animal {
    //实例变量
    private String name;//使用private修饰
    private int age;
    private String type;
    //实例方法
    public void eat() {
        System.out.println(name + "在吃饭");
    }
    public void play() {
        System.out.println(name + "在玩耍");
    }
}
public class Test {
    public static void main(String[] args) {
        Animal animal1 = new Animal();
    }
}

这个代码便完成了封装操作.和之前的代码对比,感觉变化不是很大对吧.只是把每一个变量和方法都用private修饰了.而这正是封装的关键,private修饰的变量和方法都变成了"私有的",这时候只有在这个Animal类中的代码才可以调用和修改修饰后的变量和方法.但我们可以通过接口来进行修改private修饰的值

调用示例

// 在Test类的main方法中补充调用示例
public class Test {
    public static void main(String[] args) {
        Animal animal1 = new Animal();
        animal1.setName("小狗");  // 通过setter设置属性
        animal1.setAge(3);
        System.out.println(animal1.getName());  // 通过getter获取属性
        animal1.eat();  // 调用公有方法
    }
}
实现接口
class Animal {
    //实例变量
    private String name;//使用private修饰
    private int age;
    private String type;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    //实例方法
    public void eat() {
        System.out.println(name + "在吃饭");
    }
    public void play() {
        System.out.println(name + "在玩耍");
    }
}
public class Test {
    public static void main(String[] args) {
        Animal animal1 = new Animal();
    }
}
接口的参数效验

增强 getter/setter 的示例

public void setAge(int age) {
    if (age < 0 || age > 100) {  // 添加参数校验
        System.out.println("年龄不合法!");
        return;
    }
    this.age = age;
}

这个时候我们即使代码不在该类中也可以通过留下的特定接口来获取和修改private修饰的值了

只读属性/只写属性
  • 只读属性:只提供getter不提供setter
  • 只写属性:只提供setter不提供getter

访问限定符详解

访问限定符是什么?

在 Java 里,访问限定符(也叫访问修饰符)是实现封装的关键工具,它们就像是给类、属性、方法设置的 “门禁系统”,控制着谁能访问这些代码。

访问限定符有哪些?

一共有四个

  • public:修饰的成员变量,在大部分情况下都可以访问
  • private:修饰的成员变量,只能在当前类中使用
  • default(默认:不添加任何访问限定符):只能在当前包中才可以访问
  • protected:修饰的成员变量,在同一个包或子类中才可访问
    图表如下
限定符 全局 子类 同一个包 类内部
public
protected ×
default × ×
private × × ×

static关键字

static是什么?

static 是 Java 中的一个关键字,用于修饰类、方法、变量或代码块。它的核心作用是让被修饰的成员属于类本身,而不是类的某个对象.被static修饰的成员,称为静态成员,也可以称为类成员,它不属于某个具体的对象,是所有对象共享的.

static的作用是什么?

假如我们定义一个学生(Student)类,然后里面有三个同班级的学生.我给的定义属性是名字,年龄,班级.那么我们可以很简单的想到如下的定义

package demo1;

 class Student {
    private String name;
    private int age;
    public String classroom;
}
public class Test {
    public static void main(String[] args) {
        Student stu1 = new Student();
        Student stu2 = new Student();
        Student stu3 = new Student();
    }
}

初看感觉没什么大问题,但细看还是有一个可以优化的点.就是以这个定义来new对象的话,我们每new一个都得重新设置一个班级,即使这三个学生班级相同.如果想保证这三个同学都默认是一个班级,那么我们用static修饰一下classroom使其变为类成员即可

package demo1;

 class Student {
    private String name;
    private int age;
    static String classroom;
}
public class Test {
    public static void main(String[] args) {
        Student stu1 = new Student();
        Student stu2 = new Student();
        Student stu3 = new Student();
    }
}

这个时候再new的对象就默认了classroom是同一个.原因就是因为static修饰的成员会变成类成员(静态成员).此时它已不属于某个具体的对象,是所有对象共享的.

static修饰的变量会在该类被加载时默认一同加载(无论有没有其它对象使用)

static修饰变量的访问

static修饰的变量既可以通过类直接访问,也可以通过对象来间接访问

package demo1;

 class Student {
    private String name;
    private int age;
    static String classroom = "软件工程2401班";
}
public class Test {
    public static void main(String[] args) {
        Student stu1 = new Student();
        System.out.println(Student.classroom);//通过类名直接访问
        System.out.println(stu1.classroom);//通过对象访问
    }
}
静态成员变量特征
  • 不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中
  • 既可以通过对象访问,也可以通过类名访问,但一般更推荐使用类名访问
  • 类变量存储在方法区当中
  • 生命周期伴随类的一生(即:随类的加载而创建,随类的卸载而销毁)

static修饰方法的访问

被static修饰的成员方法称为静态成员方法,是类的方法,不是某个对象所特有的.静态成员一般是通过静态方法来访问的.

package demo1;

 class Student {
    private String name;
    private int age;
    public static String classroom = "软件工程2401班";

     public static String getClassroom() {
         return classroom;
     }
 }
public class Test {
    public static void main(String[] args) {
        Student stu1 = new Student();
        System.out.println(Student.getClassroom());
    }
}

静态方法可以调用静态方法,但不能直接调用非静态方法(需要先创建对象),因为非静态方法没有伴随类的加载而加载,
静态方法不能使用this或super关键字,因为他们指向对象实例

static成员变量初始化

注意:静态成员变量⼀般不会放在构造方法中来初始化,构造方法中初始化的是与对象相关的实例属性.
静态成员变量的初始化分为两种:就地初始化和静态代码块初始化

就地初始化

在定义时直接给出初始值

public class Student{
private String name;
private String gender;
private int age;
private double score;
private static String classRoom = "1-101";
}
静态代码块初始化
public class School {
    static String schoolName;
    static int studentCount;
    static {  // 静态代码块
        schoolName = "XX中学";
        studentCount = 1000;
        System.out.println("学校初始化完成");
    }
}

静态导入包

使用import static关键字来用于导入静态方法或变量,避免重复写类名

import static java.lang.Math.sqrt; // 导入静态方法

public class Calc {
    public static void main(String[] args) {
        double result = sqrt(16); // 直接调用sqrt(),无需Math.sqrt()
    }
}

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