类和对象
- 类:类是一个模板,具有属性和行为。(空的)
- 对象(实例):对象是一个照着模板的属性产生的个体,有具体的属性和行为。(实际的)
建立一个类
例如说一个银行账户,需要具有账号、密码和余额三种属性,一个存入金额和一个取出金额的行为。
也就是说需要三个变量,两个方法。
写出代码如下,
public class Account {
String ID; //账户
String password; //密码
int balance; //余额
void addBalance(int addsum) { //addsum为存入金额的数目
balance += addsum;
}
void cutBalance(int cutsum) { //cutsum为取出的金额数目
int bool = balance - cutsum;
if(bool < 0) System.out.println("余额不足。");
else balance-=cutsum;
}
}
(这里的public(公共的)先不用管,后面会讲到。)
类的变量
成员变量
像上文代码中定义的变量ID、password 和 balance 就称为成员变量,是类Account的属性。
- 定义位置:在类中,方法体之外。
- 特点:成员变量在创建对象的时候实例化,
实例化相当于我们在创建一个银行账户时需要设定账号、密码和余额。
类的变量类型还有局部变量和类变量。
局部变量
像上文代码中,cutBalance方法中的bool就是局部变量,因为它只在cutBalance方法中有效。
- 定义位置:方法中、构造方法或者语句块中。
- 作用域:只在该方法中有效。
- 特点:方法结束后,变量就会自动销毁。
类变量
类变量是指被static关键字修饰的变量。
这里我们创建一个变量AccountNum,代表该银行中的账户数目。
如,
static int AccountNum; //银行中的账户数目
- 定义位置:也在类中,方法体之外。
- 特点:声明为 static 类型。
- 作用域:整个类,由static修饰为静态变量,就是 全局变量 。
类的构造方法(构造器)
每个类都需要有构造方法。
构造方法相当于我们创建一个账户(实例)的同时,就要设置好该账户的各种属性(变量)。
如果没有自己给类定义构造方法,Java 编译器将会为该类提供一个默认没有参数的构造方法。
- 构造方法的名称必须与类同名。
- 没有返回类型。
- 参数为类的变量
- 一个类可以有多个构造方法。(多个变量可以构造时单独设置一个)
例如类Account的构造方法如下,
public Account() {
}
public Account(String ID, String password) {
this.ID = ID;
this.password = password;
}
public Account(int balance) {
this.balance = balance;
}
public Account(String ID, String password, int balance) {
this.ID = ID;
this.password = password;
this.balance = balance;
}
(注意这里不能同时出现Account(String ID)和Account(String password)因为ID和password的类型都是String,会冲突)
类中Alt + Insert键
在IDEA中,在类中按 Alt + Insert键可以添加构造函数、Getter函数和Setter函数等。
在面向对象编程中,Setter 和 Getter 函数是用于设置和获取类的属性(成员变量)的方法。
Getter函数
顾名思义,Getter 函数用于获取类的属性值。
- 公共的(public),外部代码可以调用它访问属性的值。
- 通常不带参数,因为它们只是用来获取属性的值。
- 通常被命名为 getPropertyName,即get+变量名。
示范代码如下,
public String getID() {
return ID;
}
public String getPassword() {
return password;
}
Setter函数
Setter 函数用于设置类的属性值。
- 也是公共的(public),外部代码可以调用它设置属性的值。
- 通常具有一个参数,就是要设置的值。
- 通常被命名为 setPropertyName,即set+变量名。
示范代码如下,
public void setID(String ID) {
this.ID = ID;
}
public void setPassword(String password) {
this.password = password;
}
完整的Account类
现在才是建立一个类的基本过程。
完整代码如下,
public class Account {
String ID; //账户
String password; //密码
int balance; //余额
void addBalance(int addsum) { //addsum为存入金额的数目
balance += addsum;
}
void cutBalance(int cutsum) { //cutsum为取出的金额数目
int bool = balance - cutsum;
if(bool < 0) System.out.println("余额不足。");
else balance-=cutsum;
}
public String getID() {
return ID;
}
public String getPassword() {
return password;
}
public static int getBalance() {
return balance;
}
public void setID(String ID) {
this.ID = ID;
}
public void setPassword(String password) {
this.password = password;
}
public Account(String ID, String password, int balance) { //(三个参数的)构造方法
this.ID = ID;
this.password = password;
this.balance = balance;
}
}
创建一个对象(实例)
对象是根据类创建的。
就是说一个对象是照着类的属性创建的,并且这个对象拥有类的行为(方法)。
下面来讲讲对象创建过程中的道道。
new 一个对象
上文中我们讲到了,构造方法在创建对象时,设定对象的属性,在Java中,使用关键字 new 来创建一个新的对象。
new 表示创建一个对象,并在堆内存中开辟一块空间。
例如我们为小明创建一个账户,账号为Xiaoming@163.com,密码为123456,余额为88888。那么代码为
new Account("Xiaoming@163.com", "123456",88888);
(注意账号和密码是String型,要加" ")
这样我们就创建了一个实例,一个对象。
new关键字的作用:
- 创建一个对象。
- 为对象在堆内存中开辟一块空间。
- 为对象返回一个引用。
创建一个变量
众所周知,我们创建一个变量需要三步: 1.类型 、 2.命名 和 3.赋值
int n = 10;
那显然我们上面创建出对象的过程少了什么。
引用变量与对象
上面new关键字作用中第三点提到返回的是一个引用,一个钥匙。
就是说我们需要有一个引用变量去接受这个引用,指向我们的实例(对象)。
例如,
Account Xiaoming = new Account("Xiaoming@163.com", "123456",88888);
上面代码中,
- 声明了一个引用变量,
- 它的名字为Xiaoming,
- 类型为Account,
- 意味着Xiaoming只能引用(指向)Account类 的实例,不能引用其他类型的实例。
而等号及后面的意思为,我们使用new关键字创建了一个Account类的对象,并把该对象赋值给了Xiaoming的引用变量。
(这里就相当于c中的指针变量,指向一个变量,相当于把变量的地址赋给指针变量,如果有学过c指针应该会好理解一点。)
现在我们可以使用 Xiaoming 来访问和操作该实例中的成员变量和方法。
如,
public class Main {
public static void main(String[] args) {
Account Xiaoming = new Account("Xiaoming@163.com", "123456",88888);
Xiaoming.addBalance(10000); //存入了10000
System.out.println(Xiaoming.getBalance()); //查看现在的余额
Xiaoming.cutBalance(50000); //取出了50000
System.out.println(Xiaoming.getBalance()); //查看现在的余额
}
}
上述代码中,Xiaoming先后调用了类Account中的addBalance()和cutBalance()函数,并且通过getBalance()访问了对象中的balance变量。
public关键字
- public 是一个访问修饰符,用于指定类、方法、变量或接口的访问权限。被修饰的话,任意地点都可以访问。
- 一个 Java 源文件中只能有一个 public 类,且类名与文件名相同。
因为Java 程序是从一个 public 类的 main 函数开始执行的,(其实是main线程),就像 C 程序 是从 main() 函数开始执行一样。
细说 成员变量和类变量
static 静态变量(全局变量)
我们把static修饰的变量称为静态变量,也就是一个全局变量。
静态变量的性质:
- 全局有效:静态变量属于整个类,就是说在该类中的任何地方都可以改变这个变量。
- 唯一性:指该类只会有这一个变量,即不同Account实例共用一个静态变量,在一个Account实例里修改静态变量,另一个Account里的静态变量也会变。
下面我们给银行账户类加入全局变量AccountNum后修改后的Account类如下,并且实现Main类中不同Account实例修改AccountNum值。
public class Account {
String ID; //账户
String password; //密码
int balance; //余额
static int AccountNum; //银行中的账户数目
void addBalance(int addsum) { //addsum为存入金额的数目
balance += addsum;
}
void cutBalance(int cutsum) { //cutsum为取出的金额数目
int bool = balance - cutsum;
if(bool < 0) System.out.println("余额不足。");
else balance-=cutsum;
}
public String getID() {
return ID;
}
public String getPassword() {
return password;
}
public int getBalance() {
return balance;
}
public static int getAccountNum() {
return AccountNum;
}
public static void setAccountNum(int accountNum) {
AccountNum = accountNum;
}
public void setID(String ID) {
this.ID = ID;
}
public void setPassword(String password) {
this.password = password;
}
public Account(String ID, String password, int balance) { //(三个参数的)构造方法
this.ID = ID;
this.password = password;
this.balance = balance;
}
}
public class Main {
public static void main(String[] args) {
Account Xiaoming = new Account("Xiaoming@163.com", "123456",88888);
Xiaoming.setAccountNum(1);
System.out.println("小明银行的账户数目为" + Xiaoming.getAccountNum());
//输出:小明银行的账户数目为1
Account Xiaohong = new Account("Xiaohong@163.com","123456",66666);
Xiaohong.setAccountNum(2);
System.out.println("小红银行的账户数目为" + Xiaohong.getAccountNum());
//输出:小红银行的账户数目为2
System.out.println("小明银行的账户数目为" + Xiaoming.getAccountNum());
//输出:小明银行的账户数目为2
}
}
因为小明和小红都是同一个银行(Xiaoming、Xiaohong引用的都是同一个实例),所以改变Xiaohong的AccountNum,Xiaoming里的AccountNum也会被改变。
成员变量与类变量的区别
1、两个变量的生命周期不同
成员变量随着对象的创建而存在,随着对象的回收而释放。
静态变量随着类的加载而存在,随着类的消失而消失。
2、调用方式不同
成员变量只能被对象调用。
静态变量可以被对象调用,还可以被类名调用。
3、别名不同
成员变量所属于对象,称为实例变量。
静态变量所属于类,称为类变量。
4、数据存储位置不同
成员变量存储在堆内存的对象中,所以也叫对象的特有数据。
静态变量数据存储在方法区(共享数据区)的静态区,所以也叫对象的共享数据。
第二点的类变量可以通过类名访问的意思为,可以通过类名.类变量名来访问。
如上文Main类代码也可以这样,
public class Main {
public static void main(String[] args) {
Account Xiaoming = new Account("Xiaoming@163.com", "123456",88888);
Xiaoming.setAccountNum(1);
System.out.println("小明银行的账户数目为" + Xiaoming.AccountNum);
//输出:小明银行的账户数目为1
Account Xiaohong = new Account("Xiaohong@163.com","123456",66666);
Xiaohong.setAccountNum(2);
System.out.println("小红银行的账户数目为" + Xiaohong.AccountNum);
//输出:小红银行的账户数目为2
System.out.println("小明银行的账户数目为" + Xiaoming.AccountNum);
//输出:小明银行的账户数目为2