一、类
1.1 概述
类是组成Java程序的基本要素,是对象共同特征的描述。
- 类是一组相关属性和行为的集合;
- 可以看成是一类事务的模板,使用事务的属性特征和行为特征来描述该类事务;
- 属性:该事务的状态信息;
- 行为:该事务的功能信息。
1.2 定义类
类的定义包括两部分:类声明和类体。
1.2.1 格式
class 类名{
成员变量; //代表属性,一般是名词
成员方法; //代表行为,一般是动词
构造器;
代码块;
内部类;
}
1.2.2 类体
(1)变量的声明:用来存储属性的值——成员变量
- 格式:修饰符 数据类型 变量名 [= 初始值];
- 一般无需指定初始值,存在默认值。
public class Demo {
public static void main(String[] args) {
//创建对象格式: 类名 对象名 = new 类名();
Student s = new Student();
System.out.println("s: " + s); //s: com.demo3.Student@1540e19d
//直接输出成员变量的值
System.out.println("姓名: " + s.name); //null
System.out.println("年龄" + s.age); //0
System.out.println("--------");
//给成员变量赋值
s.name = "刘德华";
s.age = 38;
//再次输出成员变量的值
System.out.println("姓名: " + s.name); //刘德华
System.out.println("年龄: " + s.age); //18
System.out.println("---------");
}
}
class Student {
// 成员变量(属性)
String name; //姓名
int age; //年龄
}
(2)方法的定义:方法可以对类中声明的变量进行操作,即给出算法——成员方法
- 提供每一个成员变量对应的赋值方法:set和get方法;
- 若还有其他行为,也需要写上。
public void setXxx(数据类型 xxx){
this.xxx = xxx;
}
public 数据类型 getXxx(){
return xxx;
}
public class Demo01 {
public static void main(String[] args) {
//创建对象格式: 类名 对象名 = new 类名();
Student s = new Student();
System.out.println("s: " + s); //s: com.demo3.Student@1540e19d
//直接输出成员变量的值
System.out.println("姓名: " + s.name); //null
System.out.println("姓名: " + s.getName()); //null
System.out.println("年龄" + s.age); //0
System.out.println("年龄" + s.getAge()); //0
System.out.println("--------");
//给成员变量赋值
s.name = "刘德华"; //相当于 s.setName("刘德华");
s.age = 38; //相当于 s.setAge(18);
//再次输出成员变量的值
System.out.println("姓名: " + s.name); //刘德华
System.out.println("姓名: " + s.getName()); //刘德华
System.out.println("年龄: " + s.age); //18
System.out.println("年龄" + s.getAge()); //18
System.out.println("---------");
//调用成员方法
s.study(); //学习
s.eat(); //吃饭
}
}
class Student {
// 成员变量(属性)
String name; //姓名
int age; //年龄
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 void study(){
System.out.println("学习");
}
public void eat(){
System.out.println("吃饭");
}
}
1.2.3 局部变量和成员变量
- 成员变量:在变量声明部分声明的变量;
- 局部变量:在方法体中声明的变量;
区别 | 成员变量 | 局部变量 |
---|---|---|
类中位置不同 | 类中,方法外 | 方法内,方法声明上 |
初始值不同 | 有默认初始值 | 没有,使用前需完成赋值 |
内存位置不同 | 堆内存 | 栈内存 |
生命周期不同 | 随着对象的创建而存在,随着对象的消失而消失 | 对着方法的调用而存在,随着方法的运行结束而消失 |
1.3 this关键字
- 就近原则:当成员变量和局部变量同名时,输出结果将触发就近原则:谁离我近,我就用谁;
- 作用:
- 可以区分成员变量和局部变量;
- 在set方法中,this.成员变量 = 局部变量;
- 本质:this是所在方法调用者的地址值(本类)。
public class Demo01 {
public static void main(String[] args) {
Student s1 = new Student();
System.out.println("s1: " + s1); //s1: Student@1540e19d
Student s2 = new Student();
System.out.println("s2: " + s2); //s2: Student@677327b6
}
}
class Student {
String name;
int age;
public String getName() {
return name;
}
public void setName(String name) {
//this代表当前对象的内存地址值
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
//this代表当前对象的内存地址值
this.age = age;
}
}
1.4 static 关键字
static 表示静态,是 Java 中的一个修饰符,可以修饰成员。
1.4.1 实例变量和类变量的区别
- 类变量是属于是所有对象的,用 static 修饰,实例变量是属于某个对象的;
- 不同对象的实例变量将被分配不同的内存空间;所有对象的这个类变量都将分配给同一个内存空间(静态区),改变其中一个对象的这个类变量会影响其他对象的这个类变量(对象共享类变量);
Tips:JDK8 以前静态区在方法区中,JDK8 以后被挪到了堆中。
- 类变量也叫静态变量,可以通过类名访问,不需要通过创建实例就可以调用;而实例变量需 要通过对象来访问,即需要创建对象后才能进行调用;
- 类变量在程序加载类的时候初始化(类的.class 文件被加载到内存),而且只初始化一次;
- 实例变量在创建对象后才会被分配内存空间;
- 类变量的内存空间直到程序退出运行,才释放所占有的内存;实例变量随着对象的消失而消失。
Tips:类变量被该类所有对象共享;类变量不属于对象,属于类;类变量随着类的加载而加载,优先于对象存在。
示例:为每一位新来报到的同学编学号(sid),从第一名同学开始,sid为1,以此类推。学号必须是唯一的,连续的,这样以便知道,要分配给下一名新同学的学号是多少。这样我们就需要一个变量,与单独的每一个学生对象无关。
public class Demo02 {
public static void main(String[] args) {
Student s1 = new Student("张三", 23);
Student s2 = new Student("李四", 24);
Student s3 = new Student("王五", 25);
Student s4 = new Student("赵六", 26);
s1.show();
s2.show();
s3.show();
s4.show();
}
}
class Student {
// 存储到底创建了多少个学生
static int numberID = 0;
int sid;
String name;
int age;
public Student() {
// 每次创建一个学生,id都自增1
numberID++;
sid=numberID;
}
public Student(String name, int age) {
// 每次创建一个学生,id都自增1
numberID++;
sid=numberID;
this.name = name;
this.age = age;
}
public void show() {
System.out.println("sid: " + sid + "-name: " + name + "-age: " + age);
}
}
1.4.2 实例方法和类方法的区别
- 类方法也叫静态方法,用 static 修饰,在程序刚开始时初始化;
在Student类中定义静态方法:
public static void showNum() {
System.out.println("numberID:" + numberID);
}
- 类方法只能访问类的类变量,无法访问实例变量,而实例方法两者都可以访问;(静态方法能访问静态资源)
- 类方法中不存在 this 关键字;
- 类方法可以通过类名直接调用,也可以通过 类名.类方法 调用,而实例方法只能通过 对象名.实例方法([参数列表]) 访问;
public static void main(String[] args) {
// 访问类变量
System.out.println(Student.numberID);
// 调用静态方法
Student.showNum();
}
- 类方法不能被覆盖,实例方法可以被覆盖;
- 类方法的入口地址直到程序退出,才被取消;实例方法的入口地址随着对象的消失而取消;
- 若一个方法不需要操作实例变量就可以实现某种功能,就可以考虑将其声明为类方法,避免创建对象浪费内存。
1.4.3 静态原理
static 修饰的内容:
- 随着类的加载而加载,且只加载一次;
- 存储于一块固定的内存区域(静态区),可以直接被类名调用;
- 优先于对象存在,可以被所有对象共享。
二、对象
2.1 概述
用类声明的变量被称为对象,对象是真实存在的具体东西(实例)。
- 在用类声明对象后,还不行创建对象,即为声明的对象分配所有的变量(属性);
- 当使用一个类创建一个对象时,也称该出了这个类的一个实例;
- 类是抽象的,对象是具体的,类是对象的实例化(类是创建对象的模板)。
Tips:没有类就没有对象
2.2 类的实例化
2.2.1 格式
类名 对象名 = new 类名(); //在测试类中
- 用来描述一类事务的类,专业叫做JavaBean类,在JavaBean类中,不存在main方法;
- 在以前,编写了main方法的类,叫做测试类,可以在测试类中创建JavaBean类的对象,并进行赋值调用。
2.2.2 访问对象
//访问属性
对象名.成员变量;
//访问行为
对象名.成员方法([参数列表]);
2.3 构造方法
2.3.1 概述
- 构造方法是类的一种特殊方法,也叫做构造器,构造函数;
- 作用:在创建对象时,JVM会自动调用构造器给成员变量赋初始值;
2.3.2 格式
修饰符 类名([形参列表]){
方法体;
}
- 方法名与类名相同,大小写也要一致;
- 没有返回值类型,连void也没有;
- 没有具体的返回值(不能由return待会结果数据);
- 空参构造方法,默认初始化值;
- 代参构造方法,在初始化对象时,同时可以为对象进行赋值(自定义赋值,省却了去调用set方法赋值)。
public class Demo03 {
public static void main(String[] args) {
//创建对象格式: 类名 对象名 = new 类名();
Student s = new Student();
//给成员变量赋值
s.name = "刘德华";
s.age = 38;
//再次输出成员变量的值
System.out.println("姓名: " + s.name); //刘德华
System.out.println("年龄: " + s.age); //18
System.out.println("---------");
//调用成员方法
s.study(); //学习
s.eat(); //吃饭
}
}
class Student {
// 成员变量(属性)
String name; //姓名
int age; //年龄
public Student() { //空参构造
}
public Student(String name, int age) { //有参构造
this.name = name;
this.age = age;
}
// 成员方法(行为)
public void study(){
System.out.println("学习");
}
public void eat(){
System.out.println("吃饭");
}
}
- 若没有定义构造方法,系统将给出一个默认的空参构造方法;
- 若定义了构造方法,系统将不会再提供默认的构造方法;
- 带参构造方法和无参构造方法,两者方法名相同,但参数不同,构成重载;
- 无论是否使用,都应手动书写无参构造方法和带参构造方法。
执行时机:
- 创建对象时由JVM调用,不能手动调用构造方法;
- 每创建一次对象,就会调用一次构造方法。
2.4 package 包
- package语句作为Java源文件的第一条语句,指明该文件中定义的类所在的包(若缺省该语句,则指定为无名包);
- 声明包的格式为:package 顶层包名.子包名;
- 包名为公司倒写域名,如:com.baidu等,“.” 表示分割,实际创建了com和baidu两个目录,且为父子关系;
- 为使用定义在不同包中的Java类,需使用import语句来引入指定包层次下所需要的类或全部类(.*)。
例如,下面的命令行将会命令编译器载入 java_installation/java/io 路径下的所有类
import java.io.*;