面向对象的首要特征:封装
什么是封装?有什么用?
现实生活中很多例子都是封装的,比如手机,电视机,笔记本电脑,照相机,
这些都是外部有一个坚硬的壳。
封装起来,保护内部的部件。保证内部的部件是安全的。
另外,封装了之后,
对于我们使用者来说,我们是看不见内部的复杂结构了,我们也不需要关心内部有多么复杂,我们只需要操作外部壳儿上的几个按钮就可以完成操作。
封装的两个作用:
1. 保证内部结构的安全。
2. 屏蔽复杂,暴露简单。
在代码级别上,封装有什么用呢?
---- 一个类体当中的数据,假设封装之后,对于代码的调用人员来说,
不需要关心代码的复杂实现,只需要通过一个简单的入口就可以访问了。
另外,类体中安全级别较高的数据封装起来,外部人员不能随意访问,
来保证数据的安全性
Person表示人类:
–每一个人都有年龄这样的属性。
–年龄age, int类型。
先不使用封装机制,分析程序存在什么缺点?
回答:Person类的age属性对外暴露,可以在外部程序中随意访问,导致了不安全。
怎么解决这个问题?
回答:封装
public class Person {
int age;
//age属性是暴露的,在外部程序中可以随意访问,导致了不安全
}
在外部程序中访问Person这个类型中的数据。
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();
//访问一个对象的属性,通常包括两种操作,一种是读数据,一种是改数据
//读数据
System.out.println(p1.age)
//修改数据
p1.age = 50;
System.out.println(p1.age);
//在PersonTest这个外部程序中目前是可以随意对age属性进行操作的。
p1.age = -100;
System.out.println(p1.age);
//一个人的年龄值不应该为负数,程序中给年龄赋值一个负数
//按说是不符合业务要求的,但是程序目前还是让它通过了
//其实这就是一个程序的bug
//随意在这里对Person内部的数据进行访问,导致了不安全。
}
}
尝试封装一下,不再对外暴露复杂的数据,封装起来。
对外只提供简单的操作入口。
优点:
1. 数据安全了
2. 调用者也方便了
怎么进行封装,代码怎么实现?
1. 属性私有化 (使用private关键字进行修饰。)
2. 对外提供简单的操作入口。
public class Person {
private int age;
}
private表示私有的,被这个关键字修饰之后,该数据只能在本类中访问。
出了这个类,age属性就无法访问了,私有的。
public class PersonTest02 {
public static void main(String[] args) {
Person p1 = new Person();
System.out.println(p1.age);
p1.age = 20;
System.out.println(p1.age);
}
}
上面的程序,Person中的age,彻底在外部不能访问了,但是这难免有点太安全了。
age不能访问,这个程序就意义不大了。
可以提供简单的访问入口。
外部程序只能通过调用以下的代码来完成访问。
思考:你应该对外提供几个访问入口?
思考:这些操作入口是否应该是方法呢?
写一个方法专门来完成”读“ get
写一个方法专门来完成"写” set
带有static的方法,没有static的方法,分别怎么调用?(后期会具体讲static)
带有static的方法的调用:通过"类名."的方式访问
类名. 可以省略(前提是在同一个类中。)
public class MethodTest {
public static void main(String [] args) {
MethodTest.doSome();
doSome();
}
public static void doSome() {
System.out.println("do some!");
}
}
这个方法没有static,这样的方法被称为:实例方法
对象方法,对象级别的方法
目前没法解释,死记硬背
实例变量是对象变量,实例方法是对象方法
实例相关的都需要先new对象,通过**“引用.”**的方式去访问
public class MethodTest {
public static void main(String [] args) {
MethodTest mt = new MethodTest();
mt.doOther();
}
public void doOther() {
System.out.println("do other!");
}
}
实例方法导致的空指针异常
public class NullPointerTest {
public static void main(String[] args) {
User u = new User();
System.out.println(u.id); //0
u.doSome();
//当引用变空
u = null;
//id的访问,需要对象的存在
System.out.println(u.id); //空指针异常
//一个实例方法的调用也必须要有对象的存在
u.doSome(); //空指针异常
}
}
class User {
int id;
// 实例方法(对象相关的方法,对象级别的方法,应该是一个对象级别的行为)
// 方法模拟的是对象的行为动作。
public void doSome(){
System.out.println("do some");
}
接着上面的get set方法
get和set方法应该带有static,还是不应该有static呢
get和set方法应该定义为实例方法吗?
get读年龄,set改年龄,这个读和改都是操作一个对象的年龄。
没有对象,何谈年龄呢?
封装的第二步:对外提供公开的set方法和get方法作为操作入口,并且这两个方法都不带static,都是实例方法,都是对象级别的。
[修饰符列表] 返回值类型 方法名(形式参数列表) {
}
注意:Java开发规范中要求,set方法和get方法要满足以下格式。
get方法的要求:
public 返回值类型 get+属性名首字母大写(无参) {
return xxx;
}
set方法的要求:
public 返回值类型 set+属性名首字母大写(有一个参数) {
xxx = 参数;
}
如果不按照Java规范中要求的格式提供set和get方法,那么程序将不是一个通用的程序。
集成开发工具会生成get和set方法
get方法:
public int getAge() {
return age;
}
为什么括号里面没有参数呢?应不应该传参数呢?因为我调用getAge方法,目的是为了获取age属性的值,所以不需要在括号里填写参数,直接在大括号里面返回age值
set方法:
public void setAge(int nianLing) {
age = nianLing;
}
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();
p1.setAge(-100);
System.out.println(p1.getAge()); //-100
}
}
折腾半天,结果不还是-100吗
set方法可以设立关卡:
public void setAge(int nianLing) {
if(nianLing < 0 || nianLing > 150) {
System.out.println("对不起,年龄值不合法,请重新赋值!");
return; //直接终止程序的执行。
//程序能够执行到这里,说明年龄一定是合法的。
age = nianLing;
}
}
学习总结:
封装的作用:
1. 保证内部结构的安全。
2. 屏蔽复杂,暴露简单。
封装的步骤:
1. 属性私有化 (使用private关键字进行修饰。)
2. 对外提供简单的操作入口
一个属性对外提供两个get & set方法
外部程序只能通过set方法修改
只能通过get方法获取
可以在set方法中设立关卡(设立条件)
static :针对类
不带static:实例方法,对象级别,实例方法的调用必须先new对象
仅供学习使用,内容版权归B站视频老师所有。
本文围绕Java面向对象的封装特性展开。先指出不使用封装时,类属性对外暴露会导致不安全问题,接着介绍封装的实现,用private关键字修饰属性,对外提供公开的get和set实例方法作为操作入口,还提及了static方法和实例方法的调用方式。
617

被折叠的 条评论
为什么被折叠?



