封装 | B站Java学习笔记

本文围绕Java面向对象的封装特性展开。先指出不使用封装时,类属性对外暴露会导致不安全问题,接着介绍封装的实现,用private关键字修饰属性,对外提供公开的get和set实例方法作为操作入口,还提及了static方法和实例方法的调用方式。

面向对象的首要特征:封装
什么是封装?有什么用?

现实生活中很多例子都是封装的,比如手机,电视机,笔记本电脑,照相机,
这些都是外部有一个坚硬的壳。
封装起来,保护内部的部件。保证内部的部件是安全的。
另外,封装了之后,
对于我们使用者来说,我们是看不见内部的复杂结构了,我们也不需要关心内部有多么复杂,我们只需要操作外部壳儿上的几个按钮就可以完成操作。

封装的两个作用:
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站视频老师所有。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值