封装的好处:
- 封装之后,对于那个事物来说,看不到事务比较复杂的一面,只能看到简单的一面。复杂性封装,对外提供简单的入口。比如说电视机,电视机的内部实现原理是非常复杂的,我们根本不需要去了解电视机得工作原理,我们只需要会用遥控器就行。
- 封装之后才会行程真正的“对象”,真正的“独立体”。
- 封装之后意味着以后的程序可以重复使用。并且这个事务应该适用性比较强,在任何场合都可以用
- 封装之后,对于事物本身,提高了安全性【安全级别高】
- 带static的普通方法需要 “类名.方法名(实参)”的方式访问
- 不带static的普通方法需要用 “引用.方法名(实参)”的方式访问。
例如:getter和setter方法没有static关键字。
- 不带static的方法被称为 “实例方法”,实例方法只能用 “引用.方法名”的方式访问
- 对象被称为实例。
- 实例相关的有:实例变量、实例方法。
- 实例变量是对象变量。实例方法是对象方法。
- 实例相关的都需要先new对象,通过“引用.”的方式去访问。
封装的步骤:
- 所有属性私有化,使用private关键字进行修饰,修饰的所有数据只能在本类当中访问
- 对外提供简单的操作入口,也就是说以后外部程序想要访问本类当中已经进行私有化了的成员变量,必须通过这些简单的程序入口进行读取或者修改
-
- 对外提供两个公开的方法,分别是get(读取)方法和set(修改)方法。
- 想读取成员变量的属性,调用get方法
- 想修改成员变量的属性,调用set方法
- 一个变量两个方法(get和set),n个变量就会有2*n个方法
2.get方法的命名规范:
public 数据类型 get+变量名首字母大写(){
return 成员变量
}
3.set方法的命名规范:
public viod get+变量名首字母大写(形参){
成员变量 = 形参
}
4.getter方法和setter方法的调用
因为setter和getter方法都是实例方法,
所以首先就要创建对象(创建对象的前提是先要创建类)
创建完对象之后就会有引用
直接 “ 引用.方法名(实参)”就可以调用
/*
Person表示人类:
每一个人都有年龄这样的属性。
年龄age,int类型。
我这里先不使用封装机制,分析程序存在什么缺点?
Person类的age属性对外暴露,可以在外部程序中随意访问,导致了不安全。
怎么解决这个问题?
封装。
*/
// 这是没有封装的Person。
/*
class Person{
// 实例变量(属性)
int age; //age属性是暴露的,在外部程序中可以随意访问。导致了不安全。
}
*/
// 尝试封装一下
// 不再对外暴露复杂的数据,封装起来
// 对外只提供简单的操作入口。
// 优点:第一数据安全了。第二调用者也方便了。
//定义一个“人”类
class Person{
// private 表示私有的,被这个关键字修饰之后,该数据只能在本类中访问。
// 出了这个类,age属性就无法访问了。私有的。
private int age; // 每一个人年龄值不同,对象级别的属性。
private String name; // 假如每一个人姓名不同,对象级别的属性。
// 对外提供简单的访问入口(电视机的遥控器就相当于是电视机的访问入口,简单明了。)
// 外部程序只能通过调用以下的代码来完成访问
// 思考:你应该对外提供几个访问入口?
// 思考:这些操作入口是否应该是方法呢?
// 写一个方法专门来完成读。(get)
// 写一个方法专门来完成写。(set)
// get和set方法应该带有static,还是不应该有static,get和set方法应该定义为实例方法吗?
// get读年龄,set改年龄,这个读和改都是操作的一个对象的年龄。(没有对象何来年龄)
// 封装的第二步:对外提供公开的set方法和get方法作为操作入口。并且都不带static。都是实例方法。
/*
[修饰符列表] 返回值类型 方法名(形式参数列表){
}
注意:
java开发规范中有要求,set方法和get方法要满足以下格式。
get方法的要求:
public 返回值类型 get+属性名首字母大写(无参){
return 实例变量;
}
set方法的要求:
public void set+属性名首字母大写(实例变量){
this.实例变量 = 实例变量;
}
大家尽量按照java规范中要求的格式提供set和get方法。
如果不按照这个规范格式来,那么你的程序将不是一个通用的程序。
*/
// get方法
public int getAge(){
return age;
}
public String getName(){
return name;
}
// set方法
public void setAge(int age){
// 能不能在这个位置上设置关卡!!!!
if(age < 0 || age > 150){
System.out.println("对不起,年龄值不合法,请重新赋值!");
return; //直接终止程序的执行。
}
//程序能够执行到这里,说明年龄一定是合法的。
this.age = age;
}
public void setName(String name){
this.name = name;
}
}
//测试类
public class PersonTest{
//主方法,程序的主入口
public static void main(String[] args){
// 创建对象
Person p1 = new Person();
// Person的age,彻底在外部不能访问了。但是这难免有点太安全了。
// age不能访问,这个程序就意义不大了。
/*
// 读age属性的值
System.out.println(p1.age);
// 修改age属性的值
p1.age = 20;
// 读age
System.out.println(p1.age);
*/
// 通过“类名.”可以调用set和get方法吗?不行。
// 只有方法修饰符列表中有static的时候,才能使用“类名.”的方式访问
// 错误的。
//Person.getAge();
//以上代码联合,没有修改实例变量 age 和 name 之前
System.out.println(p1.getAge()); //0
System.out.println(p1.getName()); //null
//修改-->调用setAge()方法
p1.setAge(20);
p1.setName("张三");
//修改之后 --> 调用getAge()方法读取
System.out.println(p1.getAge()); //20
System.out.println(p1.getName()); //张三
// 你折腾半天了,这不是结果还是没控制住吗??????
// 对不起,年龄值不合法,请重新赋值!
p1.setAge (-100);//修改失败,因为setAge方法里面过滤了一些不合法的值,所以值任然是20
System.out.println(p1.getAge()); //20
}
}