前面文章我们分享过 ,深刻理解 面向对象思想 在于深刻理解面向对象三大基本特性和五大基本原则,而且透切理解面向对象三大基本特性是理解面向对象五大基本原则的基础。
面向对象三大特征
1.封装( Encapsulation )
封装就是把客观世界中有共同之处的事物抽象为类,并且该类可以把数据(成员变量)和方法只提供给可信任的类或者对象操作,对其他对象进行信息隐藏不可见。简而言之,一个类就是封装了数据和方法的逻辑实体,并且在对象内部某些数据和方法是私有的,外界无法访问的,防止外界意外改变或错误使用对象私有部分,达到对数据和方法不同级别保护的目的。
public class Person {
private String name;
private int age;
public void say() {
System.out.print ( “person say.” );
}
}
2.继承(Inheritance)
如果想复用已有的类的所有代码怎么办?答案是继承,继承是可以使用现有类的所有功能,并且无需重新编写原来类的前提下对功能进行扩展的方法。继承创建的新类叫做 “ 子类 ”或 “ 派生类 ”,被继承的类叫做 “基类”、“父类”、“超类”。继承有二类:实现继承与接口继承,实现继承是指直接使用基类的属性和方法而无需额外编码的能力;接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力。
public Student extends Person {
public void say() {
System.out.print ( “student say.” );
}
public void study() {
System.out.print ( “I like study.” );
}
}
代码复用
通过 “继承” 和 “组合(Composition)” 可以用来实现代码复用,上面展示了继承,组合:
public School {
private Student stu;
public School ( Student stu) {
this .stu = stu;
}
public void selfintroduction() {
stu.say();
stu.study();
}
}
这里选择 “继承” 或 “组合” 的原则:父类和子类的关系是 “ is a ” 选择继承,而父类和子类的关系是 “ has a ” 选择组合。
3.多态(Polymorphism)
多态 指一个类实例的相同方法在不同情形有不同表现形式,多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。最常见的多态就是将子类传入父类参数中,运行时调用父类方法时通过传入的子类决定具体的内部结构或行为。
public SelfIntroduction {
public void self( Person person) {
person.say();
}
}
上面这个 selfIntroduction(Personperson) 方法如果传递的是 Person 对象,输出 Person 对象的自我介绍,如果传递的是 Student 对象(Student 是 Person 子类),输出 Student 对象的自我介绍。
面向对象五大原则
1. 单一职责原则 (Single-Resposibility Principle)
一个类的功能要单一,不能包罗万象,如果要变动某个功能,只需要修改一个类或者很少量的类。比如不能把所有的职业(Student等)的行为都写入一个类中,那样会十分臃肿。
2. 开放封闭原则 (Open-Closed principle)
一个模块在扩展性方面应该是开放的而在更改性方面应该是封闭的,什么意思呢?如果不必改动类的源代码,就能扩充它的行为,那么这个软件实体设计就是满足开放封闭原则的。如果说我们预测到某种变化,或者某种变化发生了,我们应当创建抽象类来隔离以后发生的同类变化。还有就是暴露出去的方法(public 修饰)是可以让使用者重写扩展的,而隐藏私有(private 修饰)的是可以自己修改的,而且也不会影响既有用户的现在使用。
3. 里氏替换原则 (Liskov-Substituion Principle)
父类应尽可能使用接口或者抽象类来实现,子类通过实现了父类接口,能够替父类的使用地方。贯彻 GOF (Gang of Four、四人组,《设计模式》一书由四人所著)倡导的面向接口编程。这样做的好处就是,在根据新要求扩展父类接口的新子类的时候而不影响当前客户端的使用。
4. 依赖倒置原则 (Dependecy-Inversion Principle)
传统的结构化编程中,最上层的模块通常都要依赖下面的子模块来实现,称为高层依赖低层。依赖倒置原则就是要逆转这种依赖关系,让高层模块不要依赖低层模块,所以称之为依赖倒置原则。
假设 B 是较 A 低的模块,但 B 需要使用到 A 的功能,这个时候,B 不应当直接使用 A 中的具体类: 而应当由 B 定义一抽象接口,并由 A 来实现这个抽象接口,B 只使用这个抽象接口,这样就达到了依赖倒置的目的,B 也解除了对A的依赖,反过来是 A 依赖于 B 定义的抽象接口。
5.接口隔离原则 (Interface-Segregation Principle)
使用接口的地方,记住使用多个专门、专一的接口比使用单个接口包括一切要好的多,接口所定义的操作相当于对客户端的一种承诺,这种承诺当然是越少越好,越精练越好,过多的承诺就是你的大量精力和时间去维护一个冗杂的接口。