
总体介绍面向对象OOP的三大特征继承、封装、多态、抽象有时有抽象规定“动物都会吃”。封装动物的胃是私有的不能随便掏。继承狗继承自动物自动会吃。多态你说“动物吃”狗就啃骨头猫就吃鱼。抽象 ——定义统一规范——→ 继承 ——建立子类关系——→ 多态 ↑ ↑ ↑ └—————— 封装贯穿始终 ——————┘ │ └—— 重写 向上转型 ——┘一、封装性1、为什么需要封装我要用洗衣机只需要按一下开关和洗涤模式就可以了。有必要了解洗衣机内部的结构吗有必要碰电动机吗我们程序设计追求“高内聚低耦合”。高内聚类的内部数据操作细节自己完成不允许外部干涉低耦合仅对外暴露少量的方法用于使用。隐藏对象内部的复杂性只对外公开简单的接口。便于外界调用从而提高系统的可扩展性、可维护性。通俗的说把该隐藏的隐藏起来该暴露的暴露出来。这就是封装性的设计思想。Java中通过将数据声明为私有的(private)再提供公共的public方法getXxx()和setXxx()实现对该属性的操作以实现下述目的1、隐藏一个类中不需要对外提供的实现细节2、使用者只能通过事先定制好的方法来访问数据可以方便地加入控制逻辑 限制对属性的不合理操作3、便于修改增强代码的可维护性2、权限修饰符封装性的体现需要权限修饰符来配合。1、Java规定的4种权限从小到大排列private、缺省什么也不写、protected 、public2、4种权限可以用来修饰类及类的内部结构属性、方法、构造器、内部类3、具体的4种权限都可以用来修饰类和类的内部结构用来修饰类的内部结构属性、方法、构造器、内部类修饰类的话只能使用缺省、public3、示例代码测试调用类publicclassAnimalTest{publicstaticvoidmain(String[]args){AnimalanewAnimal();a.setName(大黄);a.setAge(1);a.setLegs(4);a.show();//name 大黄, age 1, legs 4a.setLegs(-6);a.show();//name 大黄, age 1, legs 0}}封装实体类publicclassAnimal{privateStringname;//名字privateintage;//年龄privateintlegs;//腿数几条腿publicvoidsetName(Stringname){this.namename;}publicStringgetName(){returnname;}publicvoidsetAge(intage){this.ageage;}publicintgetAge(){returnage;}//进行数据校验//只有满足以下两个条件才允许赋值//legs 0腿数不能是负数//legs % 2 0腿数必须是偶数。//否则就把 legs 设为 0。publicvoidsetLegs(intlegs){if(legs0legs%20){this.legslegs;}else{this.legs0;}}publicintgetLegs(){returnlegs;}publicvoidshow(){System.out.println(name name, age age, legs legs);}}二、继承性1、为什么要有继承多个类中存在相同属性和行为时将这些内容抽取到单独一个类中 那么多个类无需再定义这些属性和行为只要继承那个类即可。此处的多个类称为子类(派生类)单独的这个类称为父类(基类或超类)。可以理解为:“子类 is a 父类”类继承extends语法规则:class SubclassextendsSuperClass{ }2、作用继承的出现减少了代码冗余提高了代码的复用性。继承的出现更有利于功能的扩展。继承的出现让类与类之间产生了关系提供了多态的前提。注意不要仅为了获取其他类中某个功能而去继承子类继承了父类就继承了父类的方法和属性。在子类中可以使用父类中定义的方法和属性也可以创建自己特有的新的属性和方法。在Java 中继承的关键字用的是“extends”即子类不是父类的子集而是对父类的“扩展”。关于继承的规则仍然认为获取了父类中的私有结构只是因为封装性的影响子类不能直接访问父类中私有的(private)的成员变量和方法。一个类可以被多个子类继承Java中类的单继承性一个类只能有一个父类子父类是相对的概念子类直接继承的父类称为直接父类。间接继承的父类称为间接父类3、示例代码publicclassInheritanceTest{publicstaticvoidmain(String[]args){DogdognewDog();dog.setName(旺财);dog.setAge(3);dog.setLegs(4);//继承自 Animaldog.show();//name 旺财, age 3, legs 4//继承自 Animaldog.eat();//旺财 在吃东西//Dog 自己特有dog.bark();//旺财 在汪汪叫}}子类狗类publicclassDogextendsAnimal{publicvoidbark(){System.out.println(getName() 在汪汪叫);}}父类动物类publicclassAnimal{privateStringname;privateintage;privateintlegs;publicvoidsetName(Stringname){this.namename;}publicStringgetName(){returnname;}publicvoidsetAge(intage){this.ageage;}publicintgetAge(){returnage;}publicvoidsetLegs(intlegs){if(legs0legs%20){this.legslegs;}else{this.legs0;}}publicintgetLegs(){returnlegs;}publicvoideat(){System.out.println(name 在吃东西);}publicvoidshow(){System.out.println(name name, age age, legs legs);}}三、多态性1、定义定义同一操作作用于不同的对象可以产生不同的执行结果或者说同一接口可以有多种不同的实现。一般定义多态允许不同类的对象对同一消息作出不同的响应。调用者只需要面向父类或接口编程运行时根据对象的实际类型执行对应子类重写后的方法。Java 中的定义父类引用指向子类对象当调用父类中定义、子类中重写的方法时实际执行的是子类重写后的版本。这就是运行时多态。编译时看左边父类运行时看右边子类Animal a new Dog();a.eat();//小黑 在啃骨头。父类子类都有调用子类方法2、作用让程序面向父类或接口编程而不是面向具体实现编程。这样代码更灵活、更容易扩展也更符合开闭原则——对扩展开放对修改关闭。1、统一接口多种实现父类或接口定义统一方法子类给出不同实现。调用者只关心“它是 Animal”不关心具体是狗还是猫。2、提高代码复用性一个方法可以处理所有子类对象不用为每个子类写重复代码。3、提高可扩展性以后新增 Bird、Fish只要继承 Animal 并重写 eat()原来的 feed(Animal animal) 方法不用改。4、降低耦合调用者依赖父类或接口而不是具体子类。具体用哪个子类可以在运行时决定。5、支持框架和插件式设计Java 的很多框架比如 Spring、Servlet、JDBC都大量使用接口和多态。你写实现类框架通过接口调用你。6、便于维护修改某个子类的行为只改那个子类不影响调用方和其他子类。3、示例代码publicclassInheritanceTest{publicstaticvoidmain(String[]args){DogdognewDog();dog.setName(旺财);dog.setAge(3);dog.setLegs(4);//show() 是从父类继承来的dog.show();//name 旺财, age 3, legs 4//eat() 调用的是 Dog 重写后的版本所以输出“旺财 在啃骨头”dog.eat();//旺财 在啃骨头//bark() 是 Dog 特有的方法dog.bark();//旺财 在汪汪叫System.out.println(多态演示);//左边是父类类型 Animal右边是子类对象 new Dog()//编译时看左边父类运行时看右边子类AnimalanewDog();a.setName(小黑);a.eat();//小黑 在啃骨头。父类子类都有调用子类方法}}子类狗类publicclassDogextendsAnimal{//Dog 不用再写 setName()、setAge()、show()它自动就有//bark() 是 Dog 自己新增的方法狗会叫publicvoidbark(){System.out.println(getName() 在汪汪叫);}//Override eat() 表示重写父类的方法动物都吃东西但狗具体是“啃骨头”Overridepublicvoideat(){System.out.println(getName() 在啃骨头);}}父类动物类publicclassAnimal{privateStringname;privateintage;privateintlegs;publicvoidsetName(Stringname){this.namename;}publicStringgetName(){returnname;}publicvoidsetAge(intage){this.ageage;}publicintgetAge(){returnage;}publicvoidsetLegs(intlegs){if(legs0legs%20){this.legslegs;}else{this.legs0;}}publicintgetLegs(){returnlegs;}publicvoideat(){System.out.println(name 在吃东西);}publicvoidshow(){System.out.println(name name, age age, legs legs);}}四、抽象性1、定义抽象就是从具体事物中提取共性、本质特征忽略不相关细节形成类、抽象类或接口的过程。简单说就是“只看要什么不管怎么做”。2、作用1、隐藏细节只暴露必要的行为调用者不用关心内部实现。2、建立通用模型把共性放到父类或接口中子类只关注差异。3、支持多态父类或接口定义抽象方法子类给出不同实现运行时才能动态绑定。4、降低耦合面向抽象编程而不是面向具体实现编程。提高扩展性新增子类不用修改调用方代码。3、示例代码//Animal 是抽象定义了“动物会吃”这个共性abstractclassAnimal{abstractvoideat();// 抽象方法只规定“必须会吃”不规定“吃什么}classDogextendsAnimal{//具体实现重写eatOverridevoideat(){System.out.println(狗在啃骨头);}}classCatextendsAnimal{//具体实现重写eatOverridevoideat(){System.out.println(猫在吃鱼);}}publicclassTest{publicstaticvoidmain(String[]args){//编译时对象是Animal运行时对象是DogAnimalanewDog();a.eat();// 输出狗在啃骨头anewCat();a.eat();// 输出猫在吃鱼}}