文章目录
前言
前面我们已经基本的认识java中类和对象的基本知识。下面我们来了解一下java面向对象三大特征之一的封装性。
问题的引入:
当我们创建一个类的对象以后,我们可以通过“对象.属性”的方式,对对象的属性来进行赋值。这里,赋值操作要受到属性的数据类型和存储范围的制约。除此之外,没有其它制约条件。但是,在实际问题中,我们额往往需要给属性赋值加入额外的限制条件。这个条件不能在属性声明时体现,我们只能通过方法进行限制条件的添加.
一、封装性是什么?
把对象的属性和操作(或服务)结合为一个独立的整体,并尽可能隐藏对象的内部实现细节。封装是一种信息隐藏技术,在java中通过关键字private,protected和public实现封装,封装实际上是使用方法将类的数据隐藏起来,控制用户对类的修改和访问数据的程度。
简单来说,就是把想隐藏的隐藏起来,应该暴露的给暴露出来 。
下面我们为了更好的了解到封装性的体现,引入权限修饰符的概念.
二、概念理解
在前面的学习中我们对修饰符并不陌生,比如在方法中常见的修饰符public. 而在java中规定了4种权限(从小到大): private,缺省,protected,public. 这四种权限可以用来修饰类和类内部的结构。这样我们可以给出定义成员变量和方法的规范格式:
- // 定义成员变量
- [权限修饰符] 变量类型 变量名;
- [权限修饰符] 变量类型 变量名=初始值;
- // 定义成员方法
- [权限修饰符] 返回值类型 方法名 (形参列表) { 方法体 } ;
当然在后续学习中我们也可以加入static , final等修饰符来进行修饰。在本章中我们先体会最基本的封装性的概念。
2.修饰符的访问权限
修饰符 | 类内部 | 同一个包 | 不同包的子类 | 同一个工程 |
private | √ | |||
缺省 | √ | √ | ||
protected | √ | √ | √ | |
public | √ | √ | √ | √ |
- private:访问仅限于包含类型。只有包含该成员的类可以存取
- 缺省:没有任何权限修饰符进行修饰,允许在同一个包下的不同类进行访问
- protected:访问仅限于包含类或从包含类派生的类型。只有包含该成员的类以及继承的类可以存取.
- public:访问不受限制。
3.调试
为了方便起见,我们这里只运行private和public这两个修饰符。
以下代码在目录 src中的包 student.xiaobaixuejava下的两个Order和OrderTest内部类中进行。
package student.xiaobaixuejava;
public class Order {
private int age; //声明私有属性
public String name;//声明公开属性
}
package student.xiaobaixuejava;
public class OrderTest {
public static void main(String[] args) {
Order order=new Order(); // 创建对象
order.name="小明";
//order.age=15; //编译错误
System.out.println(order.name);
// System.out.println(order.age); //无法打印输出
}
}
从以上结果中我们可以看出private只有在它自己内部的类中才可以调用,即使在同一包下不同的类中也不可以随意调用。 就像一只猫被关进箱子里,只有箱子的内部才知道猫是生是死。我们在外面只知道猫存在,却无法进行判断。
三、封装性体现的方法
从前言中我们知道,引入封装性是为了防止类内部的属性被人为的随意修改,从而让数据与实际不符。这与我们写代码的初衷是相悖的。
例如:
public class Student { int leg; int age; }
public class StudentTest { public static void main(String[] args) { //创建学生类的对象 Student student =new Student(); student.age=-5; student.leg=3; System.out.println(student.leg); System.out.println(student.age); } }
显然,这样随意的赋值修改与实际是不合理的。
而怎样解决呢?
这时我们可以将类的属性 Xxx 和方法进行私有化(private) ,提供公共的(public)方法来获取 (getXxx)和设置(setXxx) 私有的方法和属性。值得一提的是,通过使用权限修饰符和get,set方法只是封装性的一种体现,并不等于封装 。
下面举个例子
public class Student { int leg; public void setLeg(int l){ if (l >=0 && l%2==0){ leg=l; }else System.out.println("该数据异常"); } public int getLeg(){ return leg; } }
public class StudentTest { public static void main(String[] args) { //创建学生类的对象 Student student =new Student(); student.setLeg(2); // 将实参传到set方法的形参中 System.out.println(student.getLeg()); } }
一般这种封装方法的格式,编译器会自动的生成。这样我们就能对传入的数据进行筛选和判断,确保数据的实际性。 在使用的过程中应特别注意,set方法必须要有形参且返回值类型为void;相对来说get方法没有形参,必须要有返回值类型以及返回的值或者变量。