上篇文章我们初步认识了类与对象,接下来我们继续学习类和对象的相关知识点
1. 封装
1.1 封装的概念
面向对象程序三大特性:封装、继承、多态(注意:这是面向对象的特征,而不是语言的特征);而类和对象阶段,主要研究的就是封装特性。何为封装呢?简单来说 就是套壳屏蔽细节
比如:对于手机这个复杂设备来说,里面有cpu,电池,摄像头等等复杂的内部结构来完成一系列功能,但是实际上用户不需要关心内部的这些结构是如何运行完成这一系列功能的,只需要开机,关机,用手指去操控屏幕就行,所以手机在出厂时,在外部套上壳 子,将内部实现细节隐藏起来,完成封装
封装的概念:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行 交互
1.2 访问限定符
public:谁都可以用,比较常见
protected:主要用在继承中,后面会详见
default:若定义成员变量时未加访问限定符就是默认为default
private:只有自己类可以访问,别的类都不行,常用于封装中
class Student{
public String name="zhangsan";
public int age = 18;
private int sore = 100;
public int getSore() {
return sore;
}
public void setSor(int sore) {
this.sore = sore;
}
}
public class Date {
public static void main(String[] args) {
Student s1 = new Student();
//System.out.println(s1.sore); 会报错
s1.setSor(99);
System.out.println(s1.getSore());
}
}
对于用private修饰的成员变量我们不能直接访问,但是可以通过get(),set()方法修改和使用成员变量;get(),set()方法可以自动生成
2. 封装扩展之包
2.1 包的概念
在面向对象体系中,提出了一个软件包的概念,即:为了更好的管理类,把多个类收集在一起成为一组,称为软件包。有点类似于目录。比如:为了更好的管理电脑中的歌曲,一种好的方式就是将相同属性的歌曲放在相同文件 下,也可以对某个文件夹下的音乐进行更详细的分类。包实际上就是文件夹
在Java中也引入了包,包是对类、接口等的封装机制的体现,是一种对类或者接口等的很好的组织方式,比如:一 个包中的类不想被其他包中的类使用。包还有一个重要的作用:在同一个工程中允许存在相同名称的类,只要处在 不同的包中即可
2.2 导入包中的类
Java 中已经提供了很多现成的类供我们使用。比如:我们可以使用java.util.Scanner导入java.util包中的Scanner类
import java.util.Scanner;
public class Date {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int a = s.nextInt();
System.out.println(a);
}
}
如果要使用java.util的其他类,可以用 import java.util.*,这样相当于导入了java.util包中的所有类(但并不建议)
import java.util.*;
public class Test {
public static void main(String[] args) {
Date date = new Date();
// 得到一个毫秒级别的时间戳
System.out.println(date.getTime());
}
}
但是我们更建议要用哪个类,就明确导入哪个类,上面这种做法容易引起冲突的情况
2.3 自定义包
基本规则:
在文件的最上方加上一个 package 语句指定该代码在哪个包中.
包名需要尽量指定成唯一的名字, 通常会用公司的域名的颠倒形式(例如 com.bit.demo1).
包名要和代码路径相匹配. 例如创建代码com.bit.demo1 的包,那么会存在一个对应的路径com/bit/demo1来存储代码
如果一个类没有 package 语句, 则该类被放到一个默认包中
2.4 常见的包
1. java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入
2. java.lang.reflect:java 反射编程包
3. java.net:进行网络编程开发包
4. java.sql:进行数据库开发的支持包
5. java.util:是java提供的工具程序包(集合类等) 非常重要
6. java.io:I/O编程开发包
3. static成员
在Java中,被static修饰的成员,称之为静态成员,也可以称为类成员,其不属于某个具体的对 象,是所有对象所共享的
7.2 static修饰成员变量
static修饰的成员变量,称为静态成员变量,静态成员变量最大的特性:不属于某个具体的对象,是所有对象所共享的
静态成员变量特性:
1. 不属于某个具体的对象,是类的属性,也叫类变量,所有对象共享的,不存储在某个对象的空间中
2. 既可以通过对象访问,也可以通过类名访问,但一般更推荐使用类名访问
3. 类变量存储在方法区当中
4. 生命周期伴随类的一生(即:随类的加载而创建,随类的卸载而销毁
7.2 static修饰成员方法
Java中,被static修饰的成员方法称为静态成员方法,是类的方法,不是某个对象所特有的。静态成员一般是通过静态方法来访问的
public class Student{
private static String classRoom = "Bit306";
public static String getClassRoom(){
return classRoom;
}
}
public class TestStudent {
public static void main(String[] args) {
System.out.println(Student.getClassRoom());
}
}
静态方法的特性:
1.不属于某个具体的对象,是类方法
2. 可以通过对象调用,也可以通过静态方法名调用,更推荐使用后者
3. 不能在静态方法中访问任何非静态成员变量和非静态成员方法(因为非静态方法有this参数,在静态方法中调用时候无法传递this引用)
7.4 static成员变量初始化
static成员变量有两种初始化:
就地初始化:在定义时就给出初始值
public class Student{
private String name;
private String gender;
private int age;
private double score;
private static String classRoom = "Bit306";
}
另一种时静态代码块初始化:
什么是静态代码块呢?我们接着往下看
4. 代码块
4.1. 代码块的概念和种类
概念:使用{}定义的一段代码称为代码块
代码块又可分为以下四种: 普通代码块 构造块 静态块 同步代码块(后续再谈)
4.2. 普通代码块
普通代码块:定义在方法中的代码块
\
public class Main{
public static void main(String[] args) {
{ //直接使用{}定义,普通方法块
int x = 10 ;
System.out.println("x1 = " +x);
}
int x = 100 ;
System.out.println("x2 = " +x);
}
}
4.3. 构造块
定义在类中的代码块叫做构造块,也叫做实例代码块;一般是用来初始化实例成员变量(非静态成员变量)
public class Student{
//实例成员变量
private String name;
private String gender;
private int age;
private double score;
public Student() {
System.out.println("I am Student init()!");
}
//实例代码块
{
this.name = "bit";
this.age = 12;
this.sex = "man";
System.out.println("I am instance init()!");
}
public void show(){
System.out.println("name: "+name+" age: "+age+" sex: "+sex);
}
}
public class Main {
public static void main(String[] args) {
Student stu = new Student();
stu.show();
}
}
4.4. 静态代码块
概念:用static定义的代码块叫做静态代码块;一般用来初始化静态成员变量
public class Student{
private String name;
private String gender;
private int age;
private double score;
private static String classRoom;
//实例代码块
{
this.name = "bit";
this.age = 12;
比特就业课
this.gender = "man";
System.out.println("I am instance init()!");
}
// 静态代码块
static {
classRoom = "bit306";
System.out.println("I am static init()!");
}
public Student(){
System.out.println("I am Student init()!");
}
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student();
}
}
注意事项:
静态代码块不管生成多少个对象,其只会执行一次(因为静态不属于对象)
静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的
如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行(合并)
实例代码块和构造方法只有在创建对象时才会执行(但静态代码块不一定)
若类中存在实例代码块,静态代码块,用该类创建对象时,先执行静态代码块,再执行实例代码块,再执行构造方法,代码如下:
public class Date{
private int month;
private int year;
private int day;
public Date(){//构造方法
System.out.println("构造方法执行了....");
}
{//实例代码块
System.out.println("实例代码块执行了.....");
}
static {//静态代码块
System.out.println("静态代码块执行力....");
}
public static void main(String[] args) {
Date date = new Date();
}
}
运行截图:
注意:这个执行顺序与他们的定义顺序无关,静态代码块一定比实例代码块先执行,实例代码块一定比构造方法先执行
若父类中既有静态代码块,又有实例代码块,子类也是既有静态代码块,也有实例代码块,用子类创建对象时,会先执行父类和子类的静态代码块,再执行父类的实例和构造,最后执行子类的实例和构造