封装
1.什么是封装?有什么用?
封装:将类的某些信息隐藏在类的内部,不允许外部程序直接访问,而是通过该类提供的方法来对隐藏的信息进行操作和访问。
那么思考一下:不封装,程序会有什么缺点?
代码如下:年龄怎么能是负数?所以不进行封装的age 属性是暴露的,在外部程序中可以随意访问。导致了数据的不安全。
public class Person{
//这里不使用封装机制
int age;
}
public class PersonTest{
public static void main(String[] args){
Person p1 = new Person();
//读
System.out.println(p1.age);
//写
p1.age = -100;
//读
System.out.println("您的年龄是"+p1.age);
}
}
怎么进行封装?
1.第一步:属性私有
public class Person1{
private int age;
}
2.第二步:get/set(读/写)
思考:当属性私有后,类内部的数据确实安全了,但是外部无法直接访问或修改,因此需要考虑对外部提供简单的入口实现对封装内部的访问:
那么:
- 应该对外提供几个访问入口?get/set
- 操作入口是否是用方法来实现?
既然GET/SET是方法,那么思考是否需要static进行修饰呢?
加static会报错
**get/set方法访问的是属性变量,即实例变量,是对象级别的变量,需要使用new关键字创建对象后才具有实际意义。因为你访问的不是某个类(模板)的属性,而应该是某个具体对象的属性,因此get/set方法不需要static关键字修饰,必须在实例化后才能使用get/set方法。**也就是应该去访问具体对象的属性,所以不需要static。
3.get/set语法格式
- get
[修饰符列表(无static)] 返回值类型 get属性名(驼峰原则)(){
return 属性名;
}
public int getAge(){
return age;
}
- set
[修饰符列表(无static)] void set属性名(驼峰原则)(){
方法体;
}
public void setAge(int age){
this.age = age;
}
此外,set方法可以设立关卡保证数据的安全性:
在set方法中增加选择结构:
public void setAge(int age){
if(age > 150 || age < 0){
System.out.println("error!");
}else{
this.age = age;}
}
重点思想:
在封装时,不仅基本类型的访问需要get/set方法,引用类型同样需要:(作业15)
- 账户类
public class Account{
private String id;
private double balance;
private double annualInterestRate;
//构造方法
public Account(){}
public Account(String id,double balance,double annualInterestRate){
this.id = id;
this.balance = balance;
this.annualInterestRate = annualInterestRate;
}
//setter/getter
public void setId(String id){
this.id = id;
}
public String getId(){
return id;
}
public void setBalance(double balance){
this.balance = balance;
}
public double getBalance(){
return balance;
}
public void setAnnualInterestRate(double annualInterestRate){
this.annualInterestRate = annualInterestRate;
}
public double getAnnualInterestRate(){
return annualInterestRate;
}
//存钱方法
public void deposit(double money){
//this.getBalance() = this.getBalance()+money;
this.setBalance(this.getBalance()+money);//调用set/get方法
System.out.println("成功存入:"+money);
}
//取钱方法
public void withdraw(double money){
if(this.getBalance() < money){
System.out.println("余额不足,取钱失败");
return;
}
this.setBalance(this.getBalance()-money);
System.out.println("成功取出:"+money);
}
}-
- 顾客类
public class Customer{
private String name;
private Account act;
public Customer(){}
public Customer(String name,Account act){
this.name = name;
this.act = act;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAct(Account act){
this.act = act;
}
public Account getAct(){
return act;
}
}
- 测试类
public class Homework02{
public static void main(String[] args){
Account a = new Account("1000",2000,1.23);
Customer c = new Customer("Jane Smith",a);
//存入100
//取出960
//取出2000
System.out.println("打印"+c.getName()+"的基本信息:");
c.getAct().deposit(100);//这里不能写c.act.deposit();
c.getAct().withdraw(960);
c.getAct().withdraw(2000);
}
}
注意在封装情况下,从外部类不管是访问基本类型的属性还是引用类型的属性,想要访问封装内部的属性只能通过set/get方法去访问
,但是在封装类内部可以直接访问私有属性