面向对象四大特征:编程
1、抽象
抽象就是将一类实体的共同特性抽象出来,封装在一个新的概念(类) 中,因此抽象是面向对象语言的基础。好比鸟就是一个对象,可是咱们在研究这个对象的时候把它的一些同类放到一块儿,一块儿来考虑,并且抽象的时候,只考虑咱们感兴趣的一些数据;假设你本身是一个普通人,那么你可能关心的数据是,鸟类飞行的方法,鸟类吃东西的方法;假设你本身是一个生物专家,那么你可能关心的数据时,鸟类的体重,鸟类的爪子的大小,鸟类的食量等等。
咱们能够经过抽象处理复杂性。例如,人们不会把一辆汽车想象成由几万个互相独立的部分所组成的一套装置,而是把汽车想成一个具备本身独特行为的对象。这种抽象令人们能够很容易地将一辆汽车开到杂货店,而不会因组成汽车各部分零件过于复杂而不知所措。他们能够忽略引擎、传动及刹车系统的工做细节,将汽车做为一个总体来加以利用。ui
2、封装
在面向对象语言中,封装特性是由类来体现的。咱们将现实生活中的一类实体定义成类,其中包括属性和行为(在Java中就是方法),就好像人类,能够具备name,gender,age等属性,同时也具备eat(),sleep(),咱们在行为中实现必定的功能,也可操做属性,这是面向对象的封装特性;
封装是将代码及其处理的数据绑定在一块儿的一种编程机制,该机制保证了程序和数据都不受外部干扰且不被误用。能够理解为把它想成一个黑匣子,它能够阻止在外部定义的代码随意访问内部代码和数据。对黑匣子内代码和数据的访问经过一个适当定义的接口严格控制。
封装的步骤:
一、修改属性的可见性来限制对属性的访问
二、为每一个属性建立赋值和取值的方法,用于对这些属性的访问
三、在赋值和取值的方法中,加入对属性的存储限制
封装的好处:
一、实现了专业的分工
二、类内部的结构可以自由修改
三、可以对成员进行更精确的控制
四、隐藏信息,实现细节
五、良好的封装可以减小耦合设计
3、继承
继承就像是咱们现实生活中的父子关系,儿子能够遗传父亲的一些特性,在面向对象语言中,就是一个类能够继承另外一个类的一些特性,从而能够代码重用,其实继承体现的是is-a关系,父类和子类在本质上仍是一类实体。
继承是一个对象得到另外一个对象的属性的过程。继承很重要,由于它支持了按层分类的概念。好比:藏獒是狗类的一部分,狗类又是哺乳动物的一部分,哺乳动物又是动物类的一部分。若是不使用层级的概念,咱们就不得不分别定义每一个动物的全部属性。而使用了继承,一个对象就只须要定义是它在所属类中独一无二的属性便可,由于它能够从它的父类那儿继承全部的通用属性。能够这样说,正是继承机制使一个对象成为一个更具通用类的一个特定实例成为可能。
继承的特征:
一、可传递可扩展。若类C继承类B,类B继承类A(多继承),则类C既有从类B那里继承下来的属性与方法,也有从类A那里继承下来的属性与方法,还能够有本身新定义的属性和方法。继承来的属性和方法尽管是隐式的,但还是类C的属性和方法。
二、可复用。若类B继承类A,那么创建类B时只须要再描述与基类(类A)不一样的少许特征(数据成员和成员方法)便可。这种作法能减少代码和数据的冗余度,大大增长程序的重用性。
三、可维护性。继承经过加强一致性来减小模块间的接口和界面,大大增长了程序的易维护性。对象
4、多态
多态是容许一个接口被多个同类动做使用的特性,具体使用哪一个动做与应用场合有关。多态就是经过传递给父类对象引用不一样的子类对象从而表现出不一样的行为,多态可为程序提供更好的可扩展性,一样也能够代码重用。
要理解多态性,首先要知道什么是“向上转型”。
我定义了一个子类Dog,它继承了Animal类,那么后者就是前者的父类。能够经过:
Dog d = new Dog(); 例化一个Dog对象。
但当我这样定义时: Animal a = new Dog();
它表示我定义了一个Animal类型的引用,指向新建的Dog类型的对象。因为Dog是继承自它的父类Animal,因此Animal类型的引用是能够指向Dog类型的对象的。那么这样作有什么意义呢?由于子类是对父类的一个改进和扩充,因此通常子类在功能上较父类更强大,属性较父类更独特,定义一个父类类型的引用指向一个子类的对象既可使用子类强大的功能,又能够抽取父类的共性。因此, 父类引用只能调用父类中存在的方法和属性,不能调用子类的扩展部分;由于父类引用指向的是堆中子类对象继承的父类;(可是若是强制把超类转换成子类的话,就能够调用子类中新添加而超类没有的方法了。)
同时,父类中的一个方法只有在父类中定义而在子类中没有重写的状况下,才能够被父类类型的引用调用;
对于父类中定义的方法,若是子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态链接。继承
面向对象五大原则:接口
(1)单一职责原则(Single-Resposibility Principle)ip
一个类应该仅有一个引发它变化的缘由ci
职员类例子: 好比在职员类里,将工程师、销售人员、销售经理这些状况都放在职员类里考虑,其结果将会很是混乱,在这个假设下,职员类里的每一个方法都要ifelse判断是哪一种状况,从类结构上来讲将会十分臃肿,而且上述三种的职员类型,不论哪种发生需求变化,都会改变职员类!这个是你们所不肯意看到的!it
(2)开放封闭原则(Open-Closed principle)io
对扩展是开放的,对更改是封闭的!
变化来临时,若是没必要改动软件实体裁的源代码,就能扩充它的行为,那么这个软件实体设计就是知足开放封闭原则的。若是说咱们预测到某种变化,或者某种变化发生了,咱们应当建立抽象类来隔离之后发生的同类变化。
(3)里氏替换原则(Liskov-Substituion Principle)
子类能够替换父类而且出如今父类可以出现的任何地方,贯彻GOF倡导的面向接口编程
在这个原则中父类应尽量使用接口或者抽象类来实现!
子类经过实现了父类接口,可以替父类的使用地方!
经过这个原则,咱们客户端在使用父类接口的时候,经过子类实现!
意思就是说咱们依赖父类接口,在客户端声明一个父类接口,经过其子类来实现
这个时候就要求子类必须可以替换父类所出现的任何地方,这样作的好处就是,在根据新要求扩展父类接口的新子类的时候而不影响当前客户端的使用!
(4)依赖倒置原则(Dependecy-Inversion Principle)
传统的结构化编程中,最上层的模块一般都要依赖下面的子模块来实现,也称为高层依赖低层!
因此DIP原则就是要逆转这种依赖关系,让高层模块不要依赖低层模块,因此称之为依赖倒置原则!
(5)ISP 接口隔离原则(Interface-Segregation Principle)
使用多个专门的接口比使用单个接口要好的多!
这个我有体会,在我实际编程中,为了减小接口的定义,将许多相似的方法都放在一个接口中,最后发现,维护和实现接口的时候花了太多精力,而接口所定义的操做至关于对客户端的一种承诺,这种承诺固然是越少越好,越精练越好,过多的承诺带来的就是你的大量精力和时间去维护!