包和封装也是类这部分的知识,类和对象请见-> https://nibbles.cn/java-class-obj.html
包
包(Package)是组织类的一种方式,可以防止类名冲突和提高代码的可读性。可以简单看成里面都是装类的文件夹。包是对类、接口等的封装机制的体现,是一种对类或者接口等的很好的组织方式。
导入
包的导入可以使用 import
语句导入,比如导入util
包下的Date
类可以如下:
import java.util.Date;
public class Main {
public static void main(String[] args) {
Date day = new Date();
}
}
一般来说,我们直接输入类名后,如果是自带在JDK内的,由IDEA会自动帮我们添加。
如果你也尝试了上面这样在输入 Date
后,会发现出现了两个同名类:

那么,这就是包的作用,把同名的类放在不同的包中做好区分。而且包名一般都是小写的。如果是java.
开头则代表是Java标准库的包命名空间前缀,util
代表是子包名称。
所以为了防止冲突,最好不要使用 import java.util.*;
这样通配符的形式。或者在创建对象的时候从包到具体类写全:java.util.Date date = new java.util.Date();
还有一种方式是使用 import static
导入包中的静态的方法和字段,比如下面的二元一次方法求根两种写法:
public class Main {
public static void main(String[] args) {
double a = 1.0;
double b = 2.0;
double c = 1.0;
double ret1 = (-b+Math.sqrt(b*b-4*a*c))/(2.0*a);
double ret2 = (-b-Math.sqrt(b*b-4*a*c))/(2.0*a);
System.out.println(ret1);
System.out.println(ret2);
}
}
import static java.lang.Math.*;
public class Main {
public static void main(String[] args) {
double a = 1.0;
double b = 2.0;
double c = 1.0;
double ret1 = (-b+sqrt(b*b-4*a*c))/(2.0*a);
double ret2 = (-b-sqrt(b*b-4*a*c))/(2.0*a);
System.out.println(ret1);
System.out.println(ret2);
}
}
自定义包
右键src文件夹创建的时候选择Package即可。一般的包名会使用域名的颠倒形式(如 cn.nibbles.mypackagename
)包名要和文件路径匹配(如创建的cn.nibbles.mypackage
包的文件夹目录为cn/nibbles/mypackage
)。
包内的类文件顶部都会通过package
关键字指定路径:
package cn.nibbles.mypackage;
public class NiBu {
public String name;
private int age;
public nibu(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
访问权限控制
在定义类的时候,如果没有指定成员变量/方法的访问权限,则默认(什么都不写)就是包访问权限。同样是权限的关键字还有:private
、public
、protected
访问权限的用途就是控制方法或者字段能否直接在类外使用。
如上我们已经创建好的 NiBu
类,如果在其他地方访问,那么成功导入类和创建对象后,只有name
是可以被访问到的,age
是只能在类内使用,如果不写则是不允许被其他包内的类访问。
范围 | private | 默认 | protected | public |
同个包同个类 | ✅ | ✅ | ✅ | ✅ |
同个包不同类 | ✅ | ✅ | ✅ | |
不同包内子类 | ✅ | ✅ | ||
不同包非子类 | ✅ |
protected
涉及到继承,在后续会说到
封装
面向对象程序三大特性:封装、继承、多态。接下来就是对封装概念引入。
封装的东西大家在平时生活中也总是用到。比如对于芯片,我们直接看一般就是个黑色的片状还带有引脚,主要通过引脚与电路交互,我们只需要知道各引脚的功能即可。对于一台装好的主机,我们直接看就是个机箱还带有一些接口,我们只用插好对应的外设和插头即可使用,无需关注内部元件之间的线路走向等。
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。
适当的封装,可以将对象使用接口的程序实现部分隐藏起来,不让用户看到,同时确保用户无法任意更改对象内部的重要资料,若想接触资料只能通过公开接入方法(Publicly accessible methods)的方式( 如:”getters” 和”setters”)。
——封装 (面向对象编程)(Wikipedia)
那么,其实看完这里的说明,你或许发现了,我们从前一篇文章的Getter和Setter,到现在private
访问权限的讲解,都是为了封装所服务的。
不直接通过引用来访问其中的数据,而使用公开的作为接口的方法来进行访问。隐藏并保护了对象的内部实现细节,保护数据不被意外修改或破坏。这些都是封装的作用。
static
关键字
Java中被static
修饰的成员成为静态成员,那么成员变量和成员方法都有静态和非静态的两种。而静态成员也被称为类成员,其不属于某个具体的对象,是所有对象所共享的。静态依赖于类,非静态依赖于对象。
对于“共享”的理解,比如我只需要做这一个学校的记录学生信息的学生类,大家都是一个学校所以类内的代表学生所在学校的成员变量就可以是静态成员变量,所有的对象都是一个学校的值。
package cn.nibbles.mypackage;
public class StudentInfo {
public static String school;
public String name;
public int age;
public String className;
}
静态成员变量
如上,school
就是一个静态成员变量(也成为类变量),有几点特性:首先就是,类的属性,所有对象共享的;既可通过对象访问还可以通过类名访问(更推荐后者);类变量存储在内存的方法区;类变量的生命周期同类(随着类的加载而创建,随类的卸载而销毁)
静态成员变量的访问可以通过 “类名.静态成员变量名”,如上就是通过 StudentInfo.school
访问。当然访问还是要遵循访问控制的关键字划分的权限。
静态成员变量的初始化,除了直接的就地方式 public static String school="Nameless"
,还有种方式就是静态代码块初始化。代码块的概念很简单,就是用 { }
扩起来的。静态代码块形如
package cn.nibbles.mypackage;
public class StudentInfo {
public static String school;
public String name;
public int age;
public String className;
static {
school = "Nameless";
}
}
但是静态成员变量一般不会放在构造方法中来初始化,构造方法来初始化的只是跟对象有关的。但如果非要这么做,则需要静态的Setter。
静态成员方法
同样的,被static
修饰的成员方法称为静态成员方法,是类的方法。所以也有几个特性:推荐使用“类名.静态方法名()”方式调用,如 StudentInfo.getSchool()
这样;不能在静态方法中访问任何的非静态成员变量,也不能在静态方法中调用任何非静态方法,原因是非静态是依赖于对象,就像是非静态方法内有this
参数是无法知道引用的对象的。
很棒的网站!感谢分享,谢谢站长!!@天天下载