隐藏/封装( encapsulation )
为什么需要封装?封装的作用和含义?
我要看电视,只需要按一下开关和换台就可以了。有必要了解电视机内部的结构吗?有必要碰碰显像管吗!
我要开车,......
隐藏对象内部的复杂性,只对外公开简单的接口。便于外部调用,从而提高系统的可扩展性,可维护性。
我们程序设计要追求“高内聚,低耦合”。
高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;
低耦合:仅暴露少量的方法给外部使用。
使用访问控制符,实现封装
|
同一个类 |
同一个包中 |
子类 |
所有类 |
Private |
是 |
|
|
|
default |
是 |
是 |
|
|
protected |
是 |
是 |
是 |
|
public |
是 |
是 |
是 |
是 |
Private私有的意思
如果一个属性或者方法被private修饰的话,意味着它是私有的,它这在自己类里面可以看得见。
Default 属性或者方法前面什么都不写就是default默认
如果一个属性或者方法被Default修饰的话,它这在自己类里面可以看得见。同一个包里面可以看得到。
protected 受保护的
如果一个属性或者方法被protected修饰的话,它这在自己类里面可以看得见。同一个包里面可以看得到。子类里面也可以看得到。
Public 公开的
如果一个属性或者方法被public修饰的话,它这在自己类里面可以看得见。同一个包里面可以看得到。子类里面也可以看得到,,不同的包,不同的类,不同包的子类都可以看得到。
封装要点:
类的属性的处理:
在开发中使用记住这几点:
一般情况下属性不管三七二十一全部private私有,成员变量全部私有,如果是常量的话或者static变量的话public公开,static变量可以被所有对象共享.
一些只用于本类的辅助性方法可以用private,
希望其他类调用的方法用public
package cn.bjsxt.oop.encapsulation;
public class Test1 {
private String str;
private void print() {
// private 修饰的方法或变量在自己的方法里面自己可以调
String s=str;
System.out.println("test1.print(a)");
}
// 属性或者方法前面什么都不写就是default默认
void printl() {
// private 修饰的方法或变量在自己的方法里面自己可以调
String s=str;
System.out.println("test1.print(b)");
}
/**
* 如果一个属性或者方法被public修饰的话,它这在自己类里面可以看得见。
同一个包里面可以看得到。子类里面也可以看得到,
不同的包,不同的类,不同包的子类都可以看得到。
*
*/
public void printll() {
String s=str;
System.out.println("test1.print(c)");
}
// 它这在自己类里面可以看得见。
// 同一个包里面可以看得到。子类里面也可以看得到。
protected void printlll() {
String s=str;
System.out.println("test1.print(d)");
}
}
class Test01 extends Test1{
public void pp() {
printl();
super.printl();
}
}
package cn.bjsxt.oop.encapsulation;
public class Test2 {
public static void main(String[] args) {
Test1 t = new Test1();
// 它是私有的,它这在自己类里面可以看得见。
// private类型中的print()方法不可见
// t.print();
// default 自己类里面可以看得见。同一个包里面可以看得到。
t.printl();
// public 自己类里面可以看得见。同一个包里面可以看得到。
t.printll();
// protected 自己类里面可以看得见。同一个包里面可以看得到。
t.printlll();
}
}
package cn.bjsxt.oop.encapsulation0;
//在这里需要导入我们的包
//这里用import加包名加文件名,导入包文件
import cn.bjsxt.oop.encapsulation.Test1;
public class Test3 {
public static void main(String[] args) {
Test1 t = new Test1();
// Test1类型中的print()方法不可见
// 不同的包里面不可见
// private 私有的
// t.print();
// default默认
// t.printl();
// protected 受保护的
// t.printlll();
// 不同的包里面可见
// public 公共的
t.printll();
}
}
package cn.bjsxt.oop.encapsulation0;
import cn.bjsxt.oop.encapsulation.Test1;
//Test001继承不同包下面的类Test1
public class Test001 extends Test1 {
public void ttt() {
// Private私有的 不同包下面的子类不可见
// super.print();
// print();
// protected 受保护的 不同的包子类里面也是可见的
// 自己子类继承的也是可以直接用的
printlll();
// super.父类方法()可以不在第一行,在哪一行都行。
super.printlll();
// default默认 不同的包里面的子类不可见
// printl();
// public 公共的 不同的包子类里面也是可见的
// super.父类方法()可以不在第一行,在哪一行都行。
super.printll();
// 自己子类继承的也是可以直接用的
// printll();
}
public static void main(String[] args) {
Test001 t = new Test001();
// 被Public修饰的类 公开的
// t.printll();
// protected 受保护的
// t.printlll();
t.ttt();
}
}
package cn.bjsxt.oop.encapsulation0;
public class Man {
private String name;
private String id;
private boolean man;
public static int cc;
// 常量也可以公开,但不是绝对的
public static final int XAM_SEF=120;
/** 通过它可以统一的设置它的属性
* @return
* 如果开发的话没有必要一个一个的敲,
* 通过先有的命令可以直接添加:
* 空白处右键选择Source
然后选择Generate getters and setters
在 Select getters and setters to create: 里面选择对应的属性
然后ok就可以了。*/
// 针对这些私有的属性,可以提供相应的set/get方法
// public String 以get开头,后面根属性名称,首字母大写
public String getName() {
// this可加可不加
return this.name;
}
// 如果设置呢 public void 以set开头,后面根属性名称,首字母大写,
// 括号里面加局部变量String name
public void setName(String name) {
this.name=name;
}
// 私有的布尔类型加对应的方法加的是isMan和setMan没有getMan
public boolean isMan() {
return man;
}
public void setMan(boolean man) {
this.man = man;
}
}