6.封装
Java作为一个面向对象的语言,肯定具有面向对象的特性:封装、继承、多态 ,在研究类与对象时主要对封装进行理解。什么是封装呢?用通俗的话讲就是用外壳封闭内部细节。
举一个例子:我们在使用手机时,需要用到的只有屏幕,SIM卡槽,和充电槽罢了,并不需要接触到内部的电子元件等,因此手机在出厂时就被封装了起来。
而对一个程序来说,也有很多使用者不需要接触的地方,这时候我们就可以对这一部分进行封装,隐藏部分细节。
像手机电脑这类物品可以通过外壳实现封装,那么程序该如何实现封装呢?
这就涉及到了类和访问权限的知识了。类可以将数据以及封装数据的方法结合在一起,而访问权限用来控制方法或者字段能否直接在类外使用。
6.1访问限定符
Java中有四种访问限定符:
范围 | private | default | protected | public |
同一包中的同一类 | 可以 | 可以 | 可以 | 可以 |
同一包中的不同类 | 可以 | 可以 | 可以 | |
不同包中的子类 | 可以 | 可以 | ||
不同包中的非子类 | 可以 |
public:相当于外貌,所有人都看得到。不同包之间都可以使用
default:在同一个包中可以随意使用,不能跨越包。
class Test1 {
private String a = "cpu";
public String b = "屏幕";
String c = "卡槽";
}
像c这种未声明的默认是 default
6.2 封装扩展之包
6.2.1包的概念
包是类的集合包能防止类的名字冲突
6.2.2 导入包中的类
有四种方法:
1.直接写要导入的类名
例如Date类:可以使用 java.util.Date 导入 java.util 这个包中的 Date类
public class Test {
public static void main(String[] args) {
java.util.Date date = new java.util.Date();
// 得到一个毫秒级别的时间戳
System.out.println(date.getTime());
}
}
这种调用最准确
2.使用 import语句导入包.
import java.util.Date;
public class Test {
public static void main(String[] args) {
Date date = new Date();
// 得到一个毫秒级别的时间戳
System.out.println(date.getTime());
}
}
3.使用java.util.*
这个方法可以随时调用java.util包中的其他类,当你调用类时它就会加载出来(不是全部加载过来)
缺点是:当同时导入多个包时,容易分辨不清谁调用
4.使用import static导入包中静态的方法和字段
这个用于调用类中的静态方法
但一般不推荐使用
6.3自定义包
1.在文件的最上方加上一个 package 语句指定该代码在哪个包中 .2.包名需要尽量指定成唯一的名字 , 通常会用公司的域名的颠倒形式 ( 例如 com.bit.demo1 ).3.包名要和代码路径相匹配 . 例如创建 com.bit.demo1 的包 , 那么会存在一个对应的路径 com/bit/demo1 来存储代码.4.如果一个类没有 package 语句 , 则该类被放到一个默认包中
4.比如这个类 默认在src包中
IDEA操作步骤:
1.右键src新建一个包
2.设立包的名字
在《On Java》这本书中,作者提到,Java用一种新颖的方式解决了命名冲突的问题,也就是将互联网域名翻转使用,因为域名是唯一的,所以一定不会冲突,这也是为何我们常看到com、edu、org、net等开头的包名。
3.在包中创建类, 右键包名 -> 新建 -> 类, 然后输入类名即可.
最后会自动显示出包名
7. static成员
7.1static修饰成员变量
static修饰的成员变量,称为静态成员变量, 静态成员变量的特点是:不属于你创建的对象,属于整个类,所有对象共享。
那么使用 static要注意什么呢?
1.既可以通过对象访问,也可以通过类名访问,但一般更推荐使用类名访问
public class Student{
public String name;
public String gender;
public int age;
public double score;
public static String classRoom = "306";
public Student(String han_meiMei, String 女, int i, double v) {
}
// ...
public static void main(String[] args) {
// 静态成员变量可以直接通过类名访问
System.out.println(Student.classRoom);
Student s1 = new Student("Li leilei", "男", 18, 3.8);
Student s2 = new Student("Han MeiMei", "女", 19, 4.0);
Student s3 = new Student("Jim", "男", 18, 2.6);
// 也可以通过对象访问:但是classRoom是三个对象共享的
System.out.println(s1.classRoom);
System.out.println(s2.classRoom);
System.out.println(s3.classRoom);
}
}
2.类变量存储在方法区当中,不会因为创建多个对象个多个存在。
7.2 static修饰成员方法
、
7.2.1static成员变量初始化
注意:静态成员变量一般不会放在构造方法中来初始化,构造方法中初始化的是与对象相关的实例属性
public class Student{
private String name;
private String gender;
private int age;
private double score;
private static String classRoom = "Bit306";
// ...
}
7.2.2建立静态成员方法
public static void fun1() {
System.out.println(" ");
}
但是不能在静态方法中访问任何非静态成员变量
public static String getClassRoom(){
System.out.println(this);
return classRoom;
}
// 编译失败:Error:(35, 28) java: 无法从静态上下文中引用非静态 变量 this
public static String getClassRoom(){
age += 1;
return classRoom;
}
// 编译失败:Error:(35, 9) java: 无法从静态上下文中引用非静态 变量 age
同样静态方法中不能调用任何非静态方法,因为非静态方法有this参数,在静态方法中调用时候无法传递this引用
public static String getClassRoom(){
doClass();
return classRoom;
}
// 编译报错:Error:(35, 9) java: 无法从静态上下文中引用非静态 方法 doClass()
总结: 静态方法中不能调用任何非静态方法,静态方法中不能访问任何非静态成员变量
但非静态方法中可以访问静态成员变量
7.2.3调用静态成员方法
![](https://i-blog.csdnimg.cn/direct/6bdf0ba38c77422f918504b4778584ce.png)
8.代码块
代码块共有4种:
普通代码块非静态代码块(构造代码块)/实例代码块静态代码块同步代码块
8.1普通代码块
结构:
{
//语句
}
从例子可以看出普通代码块是按照一定顺序执行的,并不是程序写下来就固定
8.2构造代码块
构造块:定义在类中的代码块(不加修饰符)。也叫:实例代码块,一般用于初始化实例成员变量
结构:
{
//语句
}
从结果很容易看出来实例代码会在对象创立之后最先调用
8.3静态代码块
静态代码块:使用static定义的代码块。一般用于初始化静态成员变量。
结构:
static {
//语句
}
从结果看出显然静态代码块比实例代码会更先执行
静态代码块>实例代码块>构造方法
注意:
静态代码块不管生成多少个对象,其只会执行一次如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行 ( 合并 )实例代码块与实例代码块都是只有在创建对象时才会执行