OK-------------Java继承_抽象类与接口的应用_第1页
OK-------------Java继承_抽象类与接口的应用_第2页
OK-------------Java继承_抽象类与接口的应用_第3页
OK-------------Java继承_抽象类与接口的应用_第4页
OK-------------Java继承_抽象类与接口的应用_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、JavaJava继承继承, ,抽象类与接口的应用抽象类与接口的应用1.继承及继承实例2.方法重写(Overwrite)3.super关键字4.方法重载(Overload)5.final修饰符6.abstract修饰符7.抽象类8.接口9.接口和抽象类对比10.接口和抽象类使用场合实例11.总结什么是继承什么是继承在第一节课的时候,我们就已经初始了继承的概念:子类自动共享父类数据结构和方法的机制,这是类之间的一种关系。继承也是提高代码复用的有力手段,当多个类之间存在相同的属性和方法时,就可以考虑继承,从这些类中抽象出父类在父类中定义这些相同的属性和方法,子类无需再定义这些相同的属性和方法,只需要

2、通过extends语句来声明继承关系即可:public class Son extends Base继承具有单根性:即一个类只能继承最多一个类。不能出现: public class Son extends Base,Base2但是Base类可以继承其他类。son:代表子类,又叫做超类。Base:代表父类,又叫做基类。继承的基本语法继承的基本语法public class 子类名 extends 父类名语法:下面,我们通过一个实际的例子来学习继承。注意:子类只能继承父类public和protected修饰的属性和方法。创建父类创建父类DoorDoor所有门都拥有开(open)和关(close)这样

3、的动作,不管是普通的门还是安全门,所以我们这里定义一个公用的父类Door类,并且默认的认为所有的门的名字都叫门。public class Door public String doorName=门; /门的名字public void open() /开门方法System.out.println(门开了!);public void close() /关门方法System.out.println(门关了);父类:创建子类创建子类CommonDoorCommonDoor和和SecurityDoorSecurityDoorpublic class CommDoor extends Door 普通门Co

4、mmDoor :public class SecurityDoor extends Door 安全门:文件结构:这三个类都放在同一个demo1包下:继承测试继承测试可以发现,在CommDoor和SecurityDoor中我们一行代码都没有写,只是继承了Door类,就可以直接使用open和close方法了。这正是继承的特点子类可以共享父类的数据和方法。public static void main(String args) CommDoor cd=new CommDoor();System.out.println(cd.doorName);cd.open();cd.close();Securit

5、yDoor sd=new SecurityDoor();System.out.println(sd.doorName);sd.open();sd.close();结果:如果说类的数量很多,那么这种优势就更加显而易见了。但是继承的弱点是:打破了封装,当父类一旦改变,子类也就可能发生变化,类的耦合度过高,不符合我们高内聚低耦合的设计原则。继承中的构造方法继承中的构造方法在父类Door中定义无参构造方法:在子类CommonDoor中定义无参构造方法:public CommDoor()System.out.println(这是子类构造方法);public Door()System.out.printl

6、n(这是父类构造方法!);测试:CommDoor cd=new CommDoor();结果:这里可以得出一个结论:实例子类时,子类默认会自动调用父类的无参构造方法。方法重写(方法重写(OverwriteOverwrite)方法重写(Overwrite)又叫方法覆盖(Override),是有继承关系的类之间的一种多态特性。如果,对于一般门,当调用open方的时候直接输出“门开了”就好了,可是对于安全门我们可能在开门之前需要做一个身份验证,以确定是否真的要开门。那么我们就需要在子类里面重写父类的open方法。public void open()System.out.println(/*-安全门,模

7、拟执行了安全验证-*/);System.out.println(门开了!);这种在子类中重新定义父类已有方法的行为就是重写,重写是多态的一种体现形式。重写测试重写测试这里重写了父类里的open方法,相当于将父类的open方法覆盖掉了。当执行:SecurityDoor sd=new SecurityDoor();sd.open();步骤如下:1、在SecurityDoor类查找open方法,如果有责直接调用,否则执行下一步2、在父类中查找open方法,如果有则调用输出结果:重写必须保证子类的方法定义完全和父类相同,不允许返回值类型不同的重写。如:public String open()super

8、super关键字关键字一般在以下情况我们会用到super关键字:1.在子类构造方法中,通过super调用父类构造方法2.在子类中访问父类被覆盖重写的方法和属性现在给Door添加构造方法,如下:public Door(String doorName)this.doorName=doorName;在SecurityDoor中可以如下定义:public SecurityDoor(String doorName,String brand)super(doorName);this.brand=brand;这里的super代表调用父类的构造方法。说明,SecurityDoor有一个自己的brand属性。s

9、upersuper关键字关键字如果在子类中重写了父类属性,如在Security中重新定义了doorName属性:private String doorName=安全门;要想再访问到父类的属性,则可以使用:super.doorName;测试:System.out.println(this.doorName+ + super.doorName);结果:方法重载(方法重载(OverloadOverload)方法重载(Overload),是类的同一功能(方法)有多种实现方式。其实重载在我们学习Math数学类的时候已经有所接触了,如下:这里有四个都叫max的方法,但是他们的参数列表不同,这样就可以实现,

10、当我们不论输入任何两个数字型(double,int,float,long)的参数的时候,都能返回最大值。不需要定义doubleMax,floatMax,intMax,longMax这样的方法。方法重载(方法重载(OverloadOverload)假设,我们的安全门现在有多种开门方式,可以使用钥匙开门,使用6位密码开门,输入房号和访客姓名请求开门三种方式。那么我们可以做如下定义:public void open(String key)System.out.println(/*-用钥匙开安全门,模拟验证钥匙是否正确-*/);System.out.println(门开了!);public void

11、open(int pwd)System.out.println(/*-用6位密码开门,模拟验证密码是否正确-*/);System.out.println(门开了!);public void open(int doorNo,String visitName)System.out.println(/*-+visitName+请求+doorNo+开门,模拟确定是否开门-*/);System.out.println(门开了!);不允许仅仅返回值不同的重载。如:public void open(String key)和public String open(String key)是不能通过编译的。重载的特

12、点:方法名都相同,参数列表不同。重载测试重载测试sd.open(123456); /使用密码开门sd.open(万能钥匙); /使用钥匙开门sd.open(1802,学员); /根据房号和访客姓名开门测试:结果:可以看到,对于不同的请求方式,程序能作出不同的响应结果。重载和重写小结重载和重写小结重载:发生在一个类中,方法名相同,参数列表不同(包括类型,个数,顺序)。重写(覆盖):发在在有继承情况的类中,子类方法和父类声明完全一致。在此基础上,我们可以回顾几个访问修饰符。final修饰符final修饰符可以修饰类,变量,方法。被final修饰的变量叫做常量,址不能被修改,如final int P

13、I=3.14;被final修饰的类不能被继承。被final修饰的方法不能被重写。abstract修饰符abstract修饰符可以修饰类,方法。被abstract修饰的类叫做抽象类,抽象类不能被实例化。被abstract修饰的方法叫做抽象方法,抽象方法没有方法体,不提供具体实现。public abstract class Door public abstract void open();所谓不能实例,就是指不能:Door door=new Door();所谓无方法体,不实现就是指:open方法没有具体的指定实现。那么定义这样的类和方法有什么用呢?我们最终当然要为这样的类和方法提供一个实现,这个实

14、现就是继承他的类,他的子类可以为抽象方法提供具体的实现。抽象类通常代表一个抽象概念,可以用一句话来概括抽象类的用途:抽象类是用来继承的。反过来可以说具体类不是用来继承的,只要有可能,我们不要从具体类继承之前我们的做法虽然实现了功能,但是没有达到思想上的真正意义。abstract修饰符使用abstract有以下几个需要遵循的原则:抽象类中可以没有抽象方法,但包含抽象方法的类就必须是抽象类。抽象方法不能是静态的。抽象类及抽象方法不能被final修饰。抽象类不象具体类那样描述一类具体事物,它是提取多种具有相似性的具体事物的共同特征而产生的 。而不是一个具体描述对象的类。同时抽象类和抽象方法其实是面向

15、契约的一种体现,抽象类就相当于一个制定者。对于某些强制要被定义和实现的方法,可以定义为抽象方法,那么一旦有子类继承该抽象类,子类就必须要按照契约来实现这个抽象方法。用抽象类来实现之前开关门的业务现在我们使用抽象类来实现之前的功能。public abstract class Door public void open()System.out.println(门开了!);public void close()System.out.println(门关了);这样看似在结果上没有任何变化,但是却已经符合抽象思维某种角度和语义就相当于,水果是抽象类,那么苹果,梨就是具体类,由具体类负责来实例对象,抽象类

16、只负责描述抽象特征和行为。注意:如果一个类继承了抽象类,但没有实现它所有的抽象方法,那么这个类也是抽象类。用抽象类来实现之前开关门的业务在Door抽象类中定义抽象方法:public abstract void theNo();如果我们现在要求每个门都必须有一个提供自己门牌号的方法由于每个门的门牌号都不一样,所以可以定义一个抽象方法,由子类具体实现内容。在子类中实现抽象方法:public void theNo() System.out.println(我是安全门No2085);相当于契约。实现契约。接口由于继承具有单根性,java不支持一个类有多个直接的父类,所以一个类只能继承一个抽象类。为解决

17、这一问题,Java引入了接口类型,弥补了Java的单继承的弱点。一个类只能有一个直接的父类,但可以实现多个接口。接口的定义语法:public interface 接口名接口只负责定义规则,不负责任何实现。实现交给实现接口的类。接口接口有以下特点:1.接口中的成员变量默认都是public static final的即静态常量。2.接口中的方法都没有方法体即可以认为都是抽象方法,但是不需要abstract关键字来修饰。3.接口不能实现接口,但可以继承多个接口。4.接口必须通过他的实现类来实例。public interface UserDAO int DEFAULT_COLOR=1;int RED=

18、2;public boolean deleteById(int id);定义接口:想一想,能不能在接口中定义私有的方法?接口的实现类实现接口:仅仅定义一个接口不去实现,就像定义一个类,但什么都不写;或者定义一个类,从来都不使用;是没有什么意义的。所以我们需要为接口编写实现类。public class UserDAOImpl implements UserDAOpublic boolean deleteById(int id) System.out.println(模拟通过id删除信息!);return true;一个类通过implements关键字来实现一个接口,而且必须实现接口中所有的方法。

19、习惯上,对于某个接口的实现类,我们一般命名规则是:接口名+Impl如UserDAOImpl是UserDAO接口的实现类。实现某个接口的类叫做该接口的实现类,而不是子类。接口的实现类一般来说,我们在实例抽象类的子类或者接口的实现类的时候,都倾向于这样的实例方法:抽象类 对象名=new 子类(); 接口 对象名=new 实现类();而不是直接new 子类或者实现类。接口和抽象类一样不能被直接实例化,只能实例化他的实现类。这样的做法是出于多态的考虑。凡是通过这种方式实例出的对象,都可以认为他的类型就是父类或者接口类。在编写方法的时候,假如只写一个方法,将基础类作为变量或参数使用,而不是使用那些特定的

20、衍生类,那么可以减少很多代码量。这种自下而上的抽象,就是java中所谓的“上溯造型”。抽象类和接口对比抽象类和接口的主要区别:1.抽象类里面可以为部分方法提供实现;接口只声明方法,不提供任何实现2.一个类只能继承一个父类,但可以实现多个接口。接口是构建松耦合的软件系统的法宝,他只描述服务或者契约,没有具体的实现,可以实现解耦。所以很多大师级人物都推崇面向接口编程,而不是面向实现编程。从设计模式的角度考虑:应当优先使用对象组合,而不是类继承。那么到底什么情况下该使用接口,什么情况下使用抽象类呢?我们通过一个实例来进行考究。接口和抽象类使用场合实例解决方案1.全部放进抽象类public abstr

21、act class Door public void open()System.out.println(门开了!);public void close()System.out.println(门关了);public void ring()System.out.println(按门铃);由于继承抽象类的子类可以使用父类的属性和方法。所以不管ring方法如何被定义,最终子类都是能拿到的。不符合我们只是有些门具有按门铃动作的要求。假设,我们现在有些门有开门,关门,按门铃三个动作,其中开门,关门动作是所有门都有的动作,而按门铃只是部分门才具有的,那么这三个动作该如何分配呢?接口和抽象类使用场合实例解决方案2.全部放进接口这里也同样面临和抽象类一样的问题,实现接口就必须实现接口中所有的方法,违反了ISP(接口

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论