封装/隐藏 encapsulation
专业解释:高内聚,低耦合,也就是说使用者在使用某样东西的时候,比如说手机,并不需要知道手机的内部结构是什么,而是会用就行,再比如说看电视,我们看电视只需要会打开电视,学会使用遥控器就可以了,我们需要知道电视机里面的电路结构吗?我们需要知道遥控器里面的结构吗?不需要...这就是封装/隐藏,将复杂的东西全部藏起来了。
在Java里面,我们使用访问控制符来实现封装:
private:
private表示的是”私有的”意思,如果一个属性被private修饰的话,表示它只能在该类中使用,而不能被其他类,更别说被其它包的其它类使用了。
举个例子:我们创建了一个包,这个包叫做Big包,然后我们在这个包里面创两个类,就分贝叫做small类和cat类吧,然后我们在里面定义了方法,并且用private修饰它。
然后我们又有了一个包,取名为different包,我们在different包创建一个名为dog类。
default:
default是默认的意思,当编程者没有定义该方法是privat或者protected或者public就会自动被认为是default,default定义的方法可以在同一个包中使用
结论:
被default定义的类,可以在该类所属的包中使用,包括子类、该包中的 其它类都可以调用在该类用default定义的方法。
protected:
protected相较于private和default使用范围更广了,不但能够在同一个包使用被protected定义的方法,而且可以在继承了被定义方法的类也就是子类中使用该方法。但不是子类就不可以用。
package Big;
publicclasssmall {
//private String str;
protectedvoid Test() {
System.out.println("李白");
}
publicstaticvoid main(String[] args) {
smalla = new small(); //以类构造
a.Test();
}
}
结果:
李白
package Big;
publicclasscat{
publicstaticvoid main(String[] args) {
smallb = new small();
b.Test();
}
}
class Bird1{
publicstaticvoid main(String[] args) {
smallc = new small();
c.Test();
}
}
结果:
李白
package different;
import Big.small; //调用Big里面的small类
publicclass dogextendssmall{
publicstaticvoid main(String[] args) {
dogd = new dog();
d.Test();
}
}
结果:
李白’
protected:
protected相较于private和default使用范围更广了,不但能够在同一个包使用被protected定义的方法,而且可以在继承了被定义方法的类也就是子类中使用该方法。但不是子类就不可以用。
package Big;
publicclasssmall {
//private String str;
protectedvoid Test() {
System.out.println("李白");
}
publicstaticvoid main(String[] args) {
smalla = new small(); //以类构造
a.Test();
}
}
结果:
李白
package Big;
publicclasscat{
publicstaticvoid main(String[] args) {
smallb = new small();
b.Test();
}
}
class Bird1{
publicstaticvoid main(String[] args) {
smallc = new small();
c.Test();
}
}
结果:
李白
package different;
import Big.small; //调用Big里面的small类
publicclass dogextendssmall{
publicstaticvoid main(String[] args) {
dogd = new dog();
d.Test();
}
}
结果:
李白’
public:
就如public的中文意思一样,公开的,它的的使用范围是最广的,能被所有类看到,也就是说public一点隐私都没有(迷之微笑),在这里就不详细打代码了,因为此前的学习过程中我们定义方法都使用的是public。
封装要点:
1、 一般的成员变量全部私有private,如果是常量或者static变量 就公开public
2、提供相应的get/set方法来访问相关属性,这些方法通常都是public,从而提供对属性的读取操作
3、一些只有本类调用的方法,可以用private
关于get/set的方法可以直接在编辑器的source里边调用:
这里有个例外就是boolean它是没有get..()的,而是is..()
get/set就是用来访问相关属性的
代码如下:
package Big;
publicclassMan {
private String name;
privateintid;
publicstaticintcc;
publicstaticfinalintMAX_VALUE= 120;
privatebooleanman;
public String getName() {
returnthis.name;
}//获取
publicvoid setName(String name) {
this.name = name;
}//修改
publicboolean isMan() {
returnman;
}//特别注意 boolean不是get而是is
publicvoid setMan(booleanman) {
this.man = man;
}
publicstaticvoid main(String[] args) {
Mans= new Man();
s.setMan(true);
System.out.println(s.isMan());
}
}
多态问题+强制转换
package learning;public class Testvoice {public static void testAnimalvoice(Aniaml c) {c.voice();if(c instanceof Cat) {((Cat)c).Catchmouse();}//疑问:c已经是Cat了为什么还有强制转型呢?因为编辑器认不出来,只会将c当做是Animal//instanceof有着“是不是”的意思}public static void main(String[] args) {Aniaml a = new Dog();Aniaml b = new Cat();Aniaml c = new Pig();((Cat)b).Catchmouse(); //Catchmouse是Cat里面特有的,不出现在Animal中,但是编辑器将b认为是Animal,所以它认为Catchmouse没有定义,所以报错//Cat a1 = (Cat)a; //要想不报错要怎么做呢?--强制转型//虽然我们可以在编辑的时候将Dog强制转换成Cat但是在运行的时候仍然会报错testAnimalvoice(a);testAnimalvoice(b);testAnimalvoice(c);}}