- 引入封装
- 为什么要封装
- 封装的好处
User对象
package com.bjpowernode.javase.day08.test003;
public class User {
int age;
}
UserTest测试对象
package com.bjpowernode.javase.day08.test003;
public class UserTest {
public static void main(String[] args) {
// 创建User对象
User user = new User();
// 访问age
// 读取年龄值【get】
System.out.println("该用户年龄:" + user.age);
// 修改年龄值【set】
user.age = 20;
// 读取年龄值【get】
System.out.println("该用户年龄:" + user.age);
// 修改年龄值【set】
// 这里的age属性是完全暴露给外部程序的,对于程序员来说可以操作User对象当中所有的细节,导致User中部分数据不安全
// 不建议这样,建议User类型进行封装,建议在外部程序中不能随意访问User对象当中的属性。这样可以保证属性的安全。
user.age = -100;
// 读取年龄值【get】
System.out.println("该用户年龄:" + user.age);
}
}
- 封装的步骤
User对象
package com.bjpowernode.javase.day08.test004;
public class User {
//属性私有化
private int age;
//set方法没有返回值,因为set方法只负责修改数据
public void setAge(int a) {
//编写业务逻辑代码进行控制
//age = a;
if(a < 0 || a > 150) {
System.out.println("对不起,你提供的 年龄不合法");
return;
}
age = a;
}
public int getAge() {
return age;
}
}
UserTest测试对象
package com.bjpowernode.javase.day08.test004;
public class UserTest {
public static void main(String[] args) {
// 创建User对象
User user = new User();
// 编译报错,age属性私有化,在外部程序中不能直接访问
// 从此之后age属性非常的安全,但是有点太安全了。
// 对于目前的程序来说,age属性在外部访问不到了
// System.out.println(user.name);
//修改
user.setAge(-100);
//读取
System.out.println(user.getAge());
}
}
- eclipse快速给类中私有变量添加相应的setter和getter方法,步骤如下:
代码位置右键 --> Source --> Generate Getters and Setters
package com.bjpowernode.javase.day08.test004;
//顾客类
public class Customer {
//属性
private int id;
private String name;
private int age;
private String addr;
//setter and getter方法
public int getId() {
return id;
}
public void setId(int id) {
//安全控制
this.id = id;
}
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 String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
}
package com.bjpowernode.javase.day08.test004;
public class CustomerTest {
public static void main(String[] args) {
Customer c = new Customer();
//私有的属性不能在外部直接访问
//c.id = 100;
//操作入口变成了只能通过set和get方法进行访问
//在set方法和get方法执行过程中可以进行安全过滤
c.setId(101010);
c.setAge(100);
c.setName("zhangsan");
c.setAddr("青岛市黄岛区辛安街道");
System.out.println(c.getId());
System.out.println(c.getName());
System.out.println(c.getAge());
System.out.println(c.getAddr());
}
}
构造方法
- 引入构造方法
package com.bjpowernode.javase.day08.test005;
public class User {
//无参数构造方法
public User() {
System.out.println("User's Default Constructor Invoke!");
}
//有参数的构造方法
public User(int i) {
System.out.println("带有int类型参数的构造器");
}
//有参数的构造方法
public User(String i) {
System.out.println("带有String类型参数的构造器");
}
//有参数的构造方法
public User(int i,String j) {
System.out.println("带有int,String类型参数的构造器");
}
}
package com.bjpowernode.javase.day08.test005;
public class ConstructorTest01 {
public static void main(String[] args) {
//创建User对象
//使用User类的构造方法来完成对象的创建
//以下程序创建了4个对象,只要构造函数调用就会创建对象,并且一定是在“堆内存”中开辟内存空间。
User u1 = new User();
User u2 = new User(10);
User u3 = new User("zhangsan");
User u4 = new User(10,"zahngsan");
// int i = sumInt(100);
//普通方法中,修饰符列表有static,调用形式:类名.方法名
ConstructorTest01.doSome();
doSome();//同一个类中可以省略类名
//普通方法中,修饰符列表中没有static ,调用形式:引用.方法名
//doOther方法在ConstructorTest01类当中,所以需要创建ConstructorTest01对象
//创建ConstructorTest01对象,调用无参数构造方法
ConstructorTest01 t = new ConstructorTest01();//一个类中没有任何构造方法的话,系统默认提供一个无参数构造器
t.doOther();
}
public static void doSome() {
System.out.println("do Some!");
}
public void doOther() {
System.out.println("do Other!");
}
}
- 构造方法的作用
package com.bjpowernode.javase.day08.test005;
// 账户类
public class Account {
//账号
private String actno;//实例变量/对象变量,也就是说,必须先有对象才能有对应的实例变量,
//余额
private double balance;
//无参构造器
public Account() {
//初始化实例变量的内存空间
//actno = null;
//balance = 0.0;
}
public Account(String s) {
actno = s;
//balance = 0.0;
}
public Account(double d) {
//actno = null;
balance = d;
}
public Account(String s,double d) {
actno = s;
balance = d;
}
public String getActno() {
return actno;
}
public void setActno(String actno) {
this.actno = actno;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
}
package com.bjpowernode.javase.day08.test005;
public class ConstructorTest02 {
public static void main(String[] args) {
//在eclipse当中怎么查看访问的是哪个属性,查看访问的是哪个方法?
//按ctrl键,鼠标移动到查看的元素上,出现下划线的时候开始单击。
//另外,在一个类中元素过多,想快速查看,在当前类中使用ctrl + o快捷键,然后输入要查找的元素名称,该名称不一定输入全名称
//创建对象
Account acc1 = new Account();
System.out.println("账号:" + acc1.getActno());
System.out.println("余额:" + acc1.getBalance());
Account acc2 = new Account("111");
System.out.println("账号:" + acc2.getActno());
System.out.println("余额:" + acc2.getBalance());
Account acc3 = new Account(100.0);
System.out.println("账号:" + acc3.getActno());
System.out.println("余额:" + acc3.getBalance());
Account acc4 = new Account("acc4-1",200.0);
System.out.println("账号:" + acc4.getActno());
System.out.println("余额:" + acc4.getBalance());
}
}
- 利用系统快捷方式快速生成构造方法
代码位置右键 --> Source --> Generate Constructor using Fields… - 快捷键,按列同步更改代码:快捷图标
package com.bjpowernode.javase.day08.test005;
public class Customer {
String name;
int no;
String addr;
//无参数构造器
public Customer() {
}
//有参数构造器
public Customer(String a, int b, String c) {
name = a;
no = b;
addr = c;
}
public Customer(int no) {
super();
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
}
package com.bjpowernode.javase.day08.test005;
public class ConstructorTest03 {
public static void main(String[] args) {
Customer c1 = new Customer();
System.out.println(c1.getNo());
System.out.println(c1.getName());
System.out.println(c1.getAddr());
Customer c2 = new Customer("zhangsan",111,"青岛市");
System.out.println(c2.getNo());
System.out.println(c2.getName());
System.out.println(c2.getAddr());
}
}
对象和引用
- 对象:目前在使用new运算符在堆内存中开辟的内存空间称为对象。
- 引用:是一个变量,不一定是局部变量,还可能是成员变量。引用保存了内存地址,指向了堆内存当中的对象。
- 所有访问实例相关的数据,都需要通过“引用.”的方式访问,因为只有通过引用才能找到对象。
- 只有一个空的引用,访问对象的实例相关的数据会出现空指针异常。
class Student{
Computer com;//com是一个引用【实例变量】
public static void doSome(){
Computer cc;//cc是一个引用【局部变量】
}
}
参数传递
- 主要研究和学习的是方法在调用的时候,涉及到参数传递的问题,到底是怎么传递数据的呢?
int i = 10;
int j = i;//i传递给j,实际上是将i变量中保存的10传递给j了,j实际上是一块全新的内存空间。
User u = 0x1234;
User u2 = u;//u传递给u2,实际上是将0x1234这个值赋值给u2了,u和u2实际上是两个不同的局部变量
//但是它们这两个变量指向堆内存中同一个java对象
- java语言当中调用的时候涉及到参数传递的问题
参数传递的是变量中的具体值
package com.bjpowernode.javase.day08.test006;
public class Test01 {
public static void main(String[] args) {
int i = 10;
add(i);//add方法调用的时候,给add方法传递了一个变量i,到底传的是什么?
System.out.println("main -->" + i);
}
public static void add(int i) {
i ++;
System.out.println("add -->" + i);
}
}
- 内容2
package com.bjpowernode.javase.day08.test006;
public class Test02 {
public static void main(String[] args) {
//User u = 0x1234;
//传递u给add方法的时候,实际上传递的是u变量中保存的值,只不过这个值是一个java对象的内存地址
User u = new User(20);
add(u);//等同于:add(0x1234);
System.out.println("main -->" + u.age);//21
}
public static void add(User u) {
u.age ++;
System.out.println("add -->" + u.age);//21
}
}
class User{
//实例变量
int age;
//构造方法
public User(int i) {
age = i;
}
}



