封装
1. 产生原因:
程序的设计中会追求“高内聚,低耦合”.
- 高内聚:是类里面数据操作自动完成,不允许外界干涉。
- 低耦合:暴露少量的方法供外界使用。
2. 封装优点:
- 提高代码的安全性
- 提高代码的复用性
- 提高代码的维护性
- 提高代码的扩展和协作
代码示例
public class Testone {
public static void main(String[] args) {
Student stu = new Student();
stu.name = "李四";//可以随意访问class Student的属性name
stu.age = 20;//可以随意访问class Student的属性age
//数据的安全性大大降低
}
}
class Student {
String name;
int age;
}
需要通过访问控制符来实现封装。
访问控制符
控制符 | 同一个类 | 同一个包 | 子类 | 所有地方 |
---|---|---|---|---|
public | ✓ | ✓ | ✓ | ✓ |
protected | ✓ | ✓ | ✓ | ✕ |
default(即不加修饰为默认) | ✓ | ✓ | ✕ | ✕ |
private | ✓ | ✕ | ✕ | ✕ |
- public :可以被该项目里面的所有包的所有类使用。
- protected:可以被同一个包的类和其它包中的子类使用。
- default:即没有修饰符时,可以被同一包中的类使用。
- private:私有的,只有在同一个类内部才能使用。
代码示例1(测试public,default,private修饰符)
package TEXE2;
public class TestEncapsulation {
public static void main(String[] args){
Age stu = new Age();
stu.ag();
stu.name = "王二";
stu.na();
}
}
class Age {
private int age;//属于本类专有的,非本类不能使用
String name;//这是默认类型即default,可以在本包里面使用,非本包不能使用
void ag(){
age = 20;
System.out.println("我的年龄是:"+age);
}
void na(){
System.out.println("我的名字是:"+name);
}
}
运行结果:
我的年龄是:20
我的名字是:王二
代码示例2
package TEXE2;
public class TestEncapsulation {
public static void main(String[] args){
Age stu = new Age();
stu.ag();
stu.age = 20;//Age类的私有的变量age不能被TestEncapsulation访问
stu.name = "王二";
stu.na();
}
}
class Age {
private int age;//属于本类专有的,非本类不能使用
String name;//这是默认类型即default,可以在本包里面使用,非本包不能使用
void ag(){
age = 20;
System.out.println("我的年龄是:"+age);
}
void na(){
System.out.println("我的名字是:"+name);
}
}
运行结果:
Error:(12, 12) java: age可以在TEXE2.Age中访问private
Age类的私有的变量age不能被TestEncapsulation访问
代码示例3(测试本包的protected修饰符)
package TEXE2;
/**
* 测试封装
* @ Dragon
*/
public class TestEncapsulation {
public static void main(String[] args){
Age stu = new Age();
stu.ag();
//stu.age = 20;
stu.name = "王二";
stu.na();
Old stu2 = new Old();
stu2.fav();
}
}
class Age {
private int age;//属于本类专有的,非本类不能使用
String name;//这是默认类型即default,可以在本包里面使用,非本包不能使用
protected String favorite;//可以在本包和”非本包“的子类使用
public int num;//属于共享的,可以在本包和非本包之间使用
void ag(){
age = 20;
System.out.println("我的年龄是:"+age);
}
void na(){
favorite = "看书";
System.out.println("我的名字是:"+name);
}
}
class Old extends Age {
void fav(){
favorite = "跑步";
System.out.println("我的爱好是:"+favorite);//子类可以使用父类的protected修饰的成员
}
}
运行结果:
我的年龄是:20
我的名字是:王二
我的爱好是:跑步
代码示例4
package TEXE2;
/**
* 测试封装
* @ Dragon
*/
public class TestEncapsulation {
public static void main(String[] args){
Age stu = new Age();
stu.ag();
//stu.age = 20;
stu.name = "王二";
stu.na();
}
}
class Age {
private int age;//属于本类专有的,非本类不能使用
String name;//这是默认类型即default,可以在本包里面使用,非本包不能使用
protected String favorite;//可以在本包和”非本包“的子类使用
public int num;//属于共享的,可以在本包和非本包之间使用
void ag(){
age = 20;
System.out.println("我的年龄是:"+age);
}
void na(){
favorite = "看书";
System.out.println("我的名字是:"+name);
}
}
class Age2 {//Age2不是Age的子类,无法访问protected修饰的成员
void na(){
favorite = "看书";
System.out.println("我的名字是:"+name);
}
}
运行结果:
Error:(39, 9) java: 找不到符号
符号: 变量 favorite
位置: 类 TEXE2.Age2
Error:(40, 37) java: 找不到符号
符号: 变量 name
位置: 类 TEXE2.Age2
Age2不是Age的子类,无法访问protected修饰的成员
代码示例3(测试非本包的default,protected修饰符)
首先先在TEXE2里面建立一个类
package TEXE2;
public class TestEncapsulation3 {
private int age;//属于本类专有的,非本类不能使用
String name;//这是默认类型即default,可以在本包里面使用,非本包不能使用
protected String favorite;//可以在本包和”非本包“的子类使用
public int num;//属于共享的,可以在本包和非本包之间使用
protected void ag(){
age = 20;
System.out.println("我的年龄是:"+age);
}
public void na(){
System.out.println("我的名字是:"+name);
}
}
然后再TEXE3里面建立一个类
package TEXE3;
/**
* 和TEXE2\TestEncapsulation.java联合测试封装问题
* author @ Dragon
*/
import TEXE2.TestEncapsulation3;
public class TestEncapsulation2 {
public static void main(String[] args){
TestEncapsulation3 stu2 = new TestEncapsulation3();
//stu2.name = "李四";
stu2.na();
Person stu3 = new Person();
stu3.fav();
}
}
class Person extends TestEncapsulation3 {
void fav(){
favorite = "你猜";//protected型的可以被非本包的子类使用
System.out.println("我喜欢的运动是:"+favorite);
}
}
运行结果:
我的名字是:null
我喜欢的运动是:你猜
如果改为
package TEXE3;
/**
* 和TEXE2\TestEncapsulation.java联合测试封装问题
* author @ Dragon
*/
import TEXE2.TestEncapsulation3;
public class TestEncapsulation2 {
public static void main(String[] args){
TestEncapsulation3 stu2 = new TestEncapsulation3();
stu2.name = "李四";
stu2.na();
Person stu3 = new Person();
stu3.fav();
}
}
class Person {
void fav(){
favorite = "你猜";//protected型的可以被非本包的子类使用
System.out.println("我喜欢的运动是:"+favorite);
}
}
运行结果:
Error:(14, 13) java: name在TEXE2.TestEncapsulation3中不是公共的; 无法从外部程序包中对其进行访问
Error:(25, 9) java: 找不到符号
符号: 变量 favorite
位置: 类 TEXE3.Person
Error:(26, 39) java: 找不到符号
符号: 变量 favorite
位置: 类 TEXE3.Person
name这是默认类型即default 可以在本包里面使用,非本包TEXE3不能使用
protected String favorite 可以在本包和”非本包“的子类使用