一、封装(Encapsulation)
概念:将对象的属性和服务结合为一个独立的整体,并尽可能隐藏内部的实现。
理解:封装的意义有两个,一是用访问控制符决定客户端程序员可以使用类的哪些部分,只把必要的部分提供给客户端程序员,让客户端程序员无法触及他们不应该触及的部分;二是允许库设计员可以改变类的内部工作方式而不用担心会影响到客户端程序员。
详解:上面的理解部分可能还是有些抽象,详细而言。什么是“让客户端程序员无法触及他们不应该触及的部分”:这部分内容通常对内部操作是必需的,但是并不是客户端程序员所需要的服务。什么是“可以改变类的内部工作方式而不用担心会影响到客户端程序员”,比如对于类的属性,通常会设置成private类型的,避免客户端程序员通过“对象.属性”的方式去访问,而是提供public的getter, setter方法。假如需要改变某个属性的类型,例如性别sex原来使用的是String类型,现在需要修改为Integer类型,那么只需要修改getter, setter方法即可,而无须修改客户端代码。
public void setSex(String sex){
if(StringUtils.isNotEmpty(sex)){
if(sex.equals('男')){
this.sex = 1;
}else if(sex.equals('女')){
this.sex = 2;
}else{
this.sex = 0;
}
}else{
System.out.println("请输入性别!"); //提示错误信息
}
}
二、继承
概念:基于基类用extends关键字生成一个导出类。导出类具有基类的全部属性和方法,并且可以在基础上扩展能力。
注意:如果没有默认的基类构造器,或者想调用基类中某个带参数的构造器,用super关键字调用基类构造器是导出类构造器中需要做的第一件事。
易混淆点:很多文章会把继承和访问权限混淆,认为没有基类某个数据或服务的访问权限就是没有继承这个项,比如这篇文章。实际上,导出类会继承基类的所有属性和方法,包括用private修饰的。只不过对于父类的private的属性和方法不能直接访问。当一个子类被实例化的时候,默认会先调用父类的构造方法对父类进行初始化,即在内存中创建一个父类对象,然后再父类对象的外部放上子类独有的属性,两者合起来成为一个子类的对象。
继承和组合的区别:is-a or has-a。
三、多态
概念:一个引用变量所指向的具体类型和这个对象发出的方法调用在编译期间并不确定,在程序运行期间才得以确定。
理解:多个子类继承父类,并且子类覆盖父类的方法,父类引用指向子类对象。