前言
前面的章节简要描述了继承的基本概念,下面我们继续学习面向对象的下一个阶段,封装。
范例
1.封装的概念
举个简单的例子,我们看电视,只需要打开开关,用遥控器进行换台就好了,不需要了解电视机的内部构造和实现原理。说的专业点,封装就是把对象的属性和操作结合作为一个独立的整体,并尽量隐藏对象的内部实现细节。
我们程序设计的目标就是“高内聚,低耦合”,高内聚就是类内部的数据操作细节自己完成,不允许外部干涉。低耦合就是仅暴露少量的方法供外部使用,尽量方便外部调用。
2.访问控制符
由于要进行封装,那么就需要访问控制符来隐藏类内部细节。java中有四种访问控制符:
Java提供了3个访问控制符:private、protected和public,分别代表了3个访问控制级别,另外还有一个不加任何访问控制符的访问控制级别,提供了4个访问控制级别。Java的访问控制级别由小到大如图所示:
图中4个访问控制级别中的default并没有对应访问控制符,当不使用任何访问控制符来修饰类或类成员时,系统默认使用该访问控制级别。这4个访问控制级别的详细介绍如下。
- private(当前类访问权限):如果类里的一个成员(包括成员变量、方法和构造器等)使用private访问控制符来修饰,则这个成员只能在当前类的内部被访问。很显然,这个访问控制符用于修饰成员变量最合适,使用它来修饰成员变量就可以把成员变量隐藏在该类的内部。
- default(包(package)访问权限):如果类里的一个成员(包括成员变量、方法和构造器等)或者一个外部类不使用任何访问控制修饰,就称它为包访问权限的,default访问控制的成员或外部类可以被相同包下的其他类访问。
- protected(子类访问权限):如果一个成员(包括成员变量、方法和构造器等)使用protected访问控制符修饰,那么这个成员既可以被同一个包中的其他类访问,也可以被不同包中的子类访问。在通常情况下,如果使用protected来修饰一个方法,通常是希望其子类来重写这个方法。
- public(公共访问权限):这是一个最宽松的访问控制级别,如果一个成员(包括成员变量、方法和构造器等)或者一个外部类使用public访问控制符修饰,那么这个成员或外部类就可以被所有类访问,不管访问类和被访问类是否处于同一个包中,是否具有父子继承关系。
范例:有这样四个类:Test、Tool、Test01、Car类的结构如下,其中Car类继承了Tool类,Test01类继承了Test类。
(1)如果Test类有一个用private修饰的成员变量id,private int id,那么只有Test本类可以访问,其他类均不可以访问。
(2)如果Test类有一个用default修饰(可以不写default,默认为default访问权限)的成员变量id,(default)int id,那么只有Test本类和同包的类可以访问,其他类均不可以访问。
(3)如果Test类有一个用protected修饰的成员变量id,protected int id,那么只有Test本类和同包的类以及子类可以访问,其他类均不可以访问。
(4)如果Test类有一个用public修饰的成员变量id,public int id,那么所有类都可以访问。
这里我就不贴图了。你懂的,哈哈哈。
3.基本对象类的编写规范
经过了前面的学习,我们现在已经掌握了一部分知识,目前完全可以写一个基本的java对象类。
范例:Person类的编写,以下是比较规范的基本对象类的编写。
package com.jwang.test;
import java.util.Date;
public class Person {
private String name;//姓名
private int age;//年龄
private String sex;//性别
private Date birth;//生日
//构造方法
public Person() {}
public Person(String name, int age, String sex, Date birth) {
this.name = name;
this.age = age;
this.sex = sex;
this.birth = birth;
}
//getter、setter方法,用来存取属性
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 getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
//toString()方法,用来显示对象
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", sex=" + sex + ", birth=" + birth + "]";
}
//equals()方法,用来判断对象内容是否相同
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (birth == null) {
if (other.birth != null)
return false;
} else if (!birth.equals(other.birth))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (sex == null) {
if (other.sex != null)
return false;
} else if (!sex.equals(other.sex))
return false;
return true;
}
}
要点:
- 类的属性一般用private修饰
- 提供相应的getter、setter方法来访问相关属性,这些方法通常是public修饰的,以提供对属性的赋值和读写操作(注意:boolean变量的get方法是is开头的!)
- 一些只用于本类的辅助性方法可用private修饰,希望其他类调用的方法用public修饰