




已阅读5页,还剩10页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
java中重载与重写的区别重载(Overloading) (1) 方法重载是让类以统一的方式处理不同类型数据的一种手段。多个同名函数同时存在,具有不同的参数个数/类型。重载Overloading是一个类中多态性的一种表现。 (2)Java的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义。调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法, 这就是多态性。 (3) 重载的时候,方法名要一样,但是参数类型和个数不一样,返回值类型可以相同也可以不相同。无法以返回型别作为重载函数的区分标准。 下面是重载的例子: package c04.answer;/这是包名 /这是这个程序的第一种编程方法,在main方法中先创建一个Dog类实例,然后在Dog类的构造方法中利用this关键字调用不同的bark方法。不同的重载方法bark是根据其参数类型的不同而区分的。 /注意:除构造器以外,编译器禁止在其他任何地方中调用构造器。 package c04.answer; public class Dog Dog() this.bark(); void bark()/bark()方法是重载方法 System.out.println(no barking!); this.bark(female, 3.4); void bark(String m,double l)/注意:重载的方法的返回值都是一样的, System.out.println(a barking dog!); this.bark(5, China); void bark(int a,String n)/不能以返回值区分重载方法,而只能以“参数类型”和“类名”来区分 System.out.println(a howling dog); public static void main(String args) Dog dog = new Dog(); /dog.bark(); Page /dog.bark(male, yellow); /dog.bark(5, China);重写(Overriding) (1) 父类与子类之间的多态性,对父类的函数进行重新定义。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。在Java中,子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写又称方法覆盖。 (2)若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法将覆盖原有的方法。如需父类中原有的方法,可使用super关键字,该关键字引用了当前类的父类。 (3)子类函数的访问修饰权限不能少于父类的; 下面是重写的例子: 概念:即调用对象方法的机制。 动态绑定的内幕: 1、编译器检查对象声明的类型和方法名,从而获取所有候选方法。试着把上例Base类的test注释掉,这时再编译就无法通过。 2、重载决策:编译器检查方法调用的参数类型,从上述候选方法选出唯一的那一个(其间会有隐含类型转化)。如果编译器找到多于一个或者没找到,此时编译器就会报错。试着把上例Base类的test(byte b)注释掉,这时运行结果是1 1。 3、若方法类型为priavte static final ,java采用静态编译,编译器会准确知道该调用哪 个方法。 4、当程序运行并且使用动态绑定来调用一个方法时,那么虚拟机必须调用对象的实际类型相匹配的方法版本。在例子中,b所指向的实际类型是TestOverriding,所以b.test(0)调用子类的test。但是,子类并没有重写test(byte b),所以b.test(byte)0)调用的是父类的test(byte b)。如果把父类的(byte b)注释掉,则通过第二步隐含类型转化为int,最终调用的是子类的test(int i)。学习总结: 多态性是面向对象编程的一种特性,和方法无关, 简单说,就是同样的一个方法能够根据输入数据的不同,做出不同的处理,即方法的 重载有不同的参数列表(静态多态性)而当子类继承自父类的相同方法,输入数据一样,但要做出有别于父类的响应时,你就要覆盖父类方法, 即在子类中重写该方法相同参数,不同实现(动态多态性)OOP三大特性:继承,多态,封装。 public class Base void test(int i) System.out.print(i); void test(byte b) System.out.print(b); public class TestOverriding extends Base void test(int i) i+; System.out.println(i); public static void main(Stringagrs) Base b=new TestOverriding(); b.test(0) b.test(byte)0) 这时的输出结果是1 0,这是运行时动态绑定的结果。重写的主要优点是能够定义某个子类特有的特征:publicclassFatherpublicvoidspeak()System.out.println(Father);publicclassSonextendsFatherpublicvoidspeak()System.out.println(son);这也叫做多态性,重写方法只能存在于具有继承关系中,重写方法只能重写父类非私有的方法。当上例中Father类speak()方法被private时,Son类不能重写出Father类speak()方法,此时Son类speak()方法相当与在Son类中定义的一个speak()方法。Father类speak()方法一但被final时,无论该方法被public,protected及默认所修饰时,Son类根本不能重写Father类speak()方法,试图编译代码时,编译器会报错。例:publicclassFatherfinalpublicvoidspeak()System.out.println(Father);publicclassSonextendsFatherpublicvoidspeak()System.out.println(son);/编译器会报错;Father类speak()方法被默认修饰时,只能在同一包中,被其子类被重写,如果不在同一包则不能重写。Father类speak()方法被protoeted时,不仅在同一包中,被其子类被重写,还可以不同包的子类重写。重写方法的规则:1、参数列表必须完全与被重写的方法相同,否则不能称其为重写而是重载。2、返回的类型必须一直与被重写的方法的返回类型相同,否则不能称其为重写而是重载。3、访问修饰符的限制一定要大于被重写方法的访问修饰符(publicprotecteddefaultprivate)4、重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常。例如:父类的一个方法申明了一个检查异常IOException,在重写这个方法是就不能抛出Exception,只能抛出IOException的子类异常,可以抛出非检查异常。而重载的规则:1、必须具有不同的参数列表;2、可以有不责骂的返回类型,只要参数列表不同就可以了;3、可以有不同的访问修饰符;4、可以抛出不同的异常;重写与重载的区别在于:重写多态性起作用,对调用被重载过的方法可以大大减少代码的输入量,同一个方法名只要往里面传递不同的参数就可以拥有不同的功能或返回值。用好重写和重载可以设计一个结构清晰而简洁的类,可以说重写和重载在编写代码过程中的作用非同一般.Java关键字this、super使用总结一、thisJava关键字this只能用于方法方法体内。当一个对象创建后,Java虚拟机(JVM)就会给这个对象分配一个引用自身的指针,这个指针的名字就是this。因此,this只能在类中的非静态方法中使用,静态方法和静态的代码块中绝对不能出现this,这在“Java关键字static、final使用总结”一文中给出了明确解释。并且this只和特定的对象关联,而不和类关联,同一个类的不同对象有不同的this。下面给出一个使用this的综合实例,以便说明问题:package org.leizhimin;public class Test6 private int number;private String username;private String password;private int x = 100;public Test6(int n) number = n; / 这个还可以写为: this.number=n;public Test6(int i, String username, String password) / 成员变量和参数同名,成员变量被屏蔽,用this.成员变量的方式访问成员变量.this.username = username;this.password = password;/ 默认不带参数的构造方法public Test6() this(0, 未知, 空); / 通过this调用另一个构造方法public Test6(String name) this(1, name, 空); / 通过this调用另一个构造方法public static void main(String args) Test6 t1 = new Test6();Test6 t2 = new Test6(游客);t1.outinfo(t1);t2.outinfo(t2);private void outinfo(Test6 t) System.out.println(-);System.out.println(t.number);System.out.println(t.username);System.out.println(t.password);f(); / 这个可以写为: this.f();private void f() / 局部变量与成员变量同名,成员变量被屏蔽,用this.成员变量的方式访问成员变量.int x;x = this.x+;System.out.println(x);System.out.println(this.x);/返回当前实例的引用private Test6 getSelf() return this;运行结果如下:-0未知空100101-0游客空100101看着上面的例子,说明在什么情况下需要用到this:第一、通过this调用另一个构造方法,用发是this(参数列表),这个仅仅在类的构造方法中,别的地方不能这么用。第二、函数参数或者函数中的局部变量和成员变量同名的情况下,成员变量被屏蔽,此时要访问成员变量则需要用“this.成员变量名”的方式来引用成员变量。当然,在没有同名的情况下,可以直接用成员变量的名字,而不用this,用了也不为错,呵呵。第三、在函数中,需要引用该函所属类的当前对象时候,直接用this。其实这些用法总结都是从对“this是指向对象本身的一个指针”这句话的更深入的理解而来的,死记不然容易忘记而且容易搞错,要理解!二、super super关键和this作用类似,是被屏蔽的成员变量或者成员方法或变为可见,或者说用来引用被屏蔽的成员变量和成员成员方法。不过super是用在子类中,目的是访问直接父类中被屏蔽的成员,注意是直接父类(就是类之上最近的超类)。下面是一个综合运用super的例子,有两个类:一个Father类,一个Father类的子类Son,通过这两个类完全演示了super的用法,一下是代码:package org.leizhimin;public class Father public String v=Father;public String x=输出了Father类的public成员变量x!;public Father() System.out.println(Father构造方法被调用!);public Father(String v)this.v=Father类的带参数构造方法!运行了.;public void outinfo()System.out.println(Father的outinfo方法被调用);public static void main(String args) / TODO 自动生成方法存根package org.leizhimin;public class Son extends Fatherpublic String v=Son;public Son() super();/调用超类的构造方法,只能放到第一行.System.out.println(Son无参数构造方法被调用!);/super();/错误的,必须放到构造方法体的最前面.public Son(String str)super(str);System.out.println(Son带参数构造方法被调用!);/覆盖了超类成员方法outinfo() public void outinfo()System.out.println(Son的outinfo()方法被调用); public void test()String v=哈哈哈哈!;/局部变量v覆盖了成员变量v和超类变量vSystem.out.println(-1-);System.out.println(v);/输出局部变量vSystem.out.println(this.v);/输出(子类)成员变量vSystem.out.println(super.v);/输出超类成员变量vSystem.out.println(-2-);System.out.println(x);/输出超类成员变量v,子类继承而来System.out.println(super.x);/输出超类成员变量vSystem.out.println(-3-);outinfo();/调用子类的outinfo()方法this.outinfo();/调用子类的outinfo()方法super.outinfo();/调用父类的outinfo()方法public static void main(String args) new Son().test();子类Son运行结果:Father构造方法被调用!Son无参数构造方法被调用!-1-哈哈哈哈!SonFather-2-输出了Father类的public成员变量x!输出了Father类的public成员变量x!-3-Son的outinfo()方法被调用Son的outinfo()方法被调用Father的outinfo方法被调用说明:次例子仅仅为了说明super的用法,实际在设计类的时候一般都尽可能私有(private)化。通过上面的例子,下面总结一下super的用法:第一、在子类构造方法中要调用父类的构造方法,用“super(参数列表)”的方式调用,参数不是必须的。同时还要注意的一点是:“super(参数列表)”这条语句只能用在子类构造方法体中的第一行。第二、当子类方法中的局部变量或者子类的成员变量与父类成员变量同名时,也就是子类局部变量覆盖父类成员变量时,用“super.成员变量名”来引用父类成员变量。当然,如果父类的成员变量没有被覆盖,也可以用“super.成员变量名”来引用父类成员变量,不过这是不必要的。第三、当子类的成员方法覆盖了父类的成员方法时,也就是子类和父类有完全相同的方法定义(但方法体可以不同),此时,用“super.方法名(参数列表)”的方式访问父类的方法。this、super的用法也不过这些,只有理解了其中的原理,才不会跌入陷阱!Java中abstract class 和 interface 的解释和他们的异同点 (一)概述 在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制。正是由于这两种机制的存在,才赋予了Java强大的 面向对象能力。abstract class和interface之间在对于抽象类定义的支持方面具有很大的相似性,甚至可以相互替换,因此很多开发者在进 行抽象类定义时对于abstract class和interface的选择显得比较随意。其实,两者之间还是有很大的区别的,对于它们的选择甚至反映出对 于问题领域本质的理解、对于设计意图的理解是否正确、合理。abstract class和interface在Java语言中都是用来进行抽象类(本文 中的抽象类并非从abstract class翻译而来,它表示的是一个抽象体,而abstract class为Java语言中用于定义抽象类的一种方法, 请读者注意区分)定义的,那么什么是抽象类,使用抽象类能为我们带来什么好处呢?在 面向对象的概念中,我们知道所有的对象都是通过类来描绘的,但是反过来却不是这样。并不是 所有的类都是用来描绘对象的(把类具体化),如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。抽象类往往用来表征我们在对问题领域进行分析、 设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。比如:如果我们进行一个图形编辑软件的开发,就会发现问题领域存在着圆、 三角形这样一些具体概念,它们是不同的,但是它们又都属于形状这样一个概念,形状这个概念在问题领域是不存在的,它就是一个抽象概念。正是因为抽象的概念 在问题领域没有对应的具体概念,所以用以表征抽象概念的抽象类是不能够实例化的。 在面向对象领域,抽象类主要用来进行类型隐藏。 我们可以构造出一个固定的一组行为的抽象描 述,但是这组行为却能够有任意个可能的具体实现方式。这个抽象描述就是抽象类,而这一组任意个可能的具体实现则表现为所有可能的派生类。好比,动物是一个抽象类,人、猴子、老虎就是具体实现的派生类,我们就可以用动物类型来隐藏人、猴子和老虎的类型。(二)从语法定义来分析在语法层面,Java语言对于abstract class和interface给出了不同的定义方式,下面以定义一个名为Demo的抽象类为例来说明这种不同。使用abstract class的方式定义Demo抽象类的方式如下:abstract class Demoabstract void method1();abstract void method2();使用interface的方式定义Demo抽象类的方式如下:interface Demovoid method1();void method2();在abstract class方式中,Demo可以有自己的数据成员,也可以有非 abstract的成员方法,而在interface方式的实现中,Demo只能够有静态的不能被修改的数据成员(也就是必须是static final 的,不过在interface中一般不定义数据成员),所有的成员方法都是abstract的。从某种意义上说,interface是一种特殊形式的 abstract class。从编程的角度来看,abstract class和interface都可以用来实现 design by contract 的思想。但是在具体的使用上面还是有一些区别的。首先,abstract class 在 Java 语言中表示的是一种继承关系,一个类只能使用一次继承关系(因为Java不支持多继承 - 转注)。但是,一个类却可以实现多个interface。也许,这是Java语言的设计者在考虑Java对于多重继承的支持方面的一种折中考虑吧。其次,在abstract class的定义中,我们可以赋予方法的默认行为。但是在interface的定义中,方法却不能拥有默认行为,为了绕过这个限制,必须使用委托,但是这会增加一些复杂性,有时会造成很大的麻烦。在 抽象类中不能定义默认行为还存在另一个比较严重的问题,那就是可能会造成维护上的麻烦。因为如果后来想修改类的界面(一般通过 abstract class 或者interface来表示)以适应新的情况(比如,添加新的方法或者给已用的方法中添 加新的参数)时,就会非常的麻烦,可能要花费很多的时间(对于派生类很多的情况,尤为如此)。但是如果界面是通过abstract class来实现的,那 么可能就只需要修改定义在abstract class中的默认行为就可以了。同样,如果不能在抽象类中定义默认行为,就会导致同样的方法实现出现在该抽象类的每一个派生类中,违反了 one rule,one place原则,造成代码重复,同样不利于以后的维护。因此,在abstract class和interface间进行选择时要非常的小心。(三)从设计理念层面分析上面主要从语法定义和编程的角度论述了abstract class和interface的区 别,这些层面的区别是比较低层次的、非本质的。本小节将从另一个层面:abstract class和interface所反映出的设计理念,来分析一下二者的区别。作者认为,从这个层面进行分析才能理解二者概念的本质所在。前面已经提到过,abstract class在Java语言中体现了一种继承关系,要想使得 继承关系合理,父类和派生类之间必须存在is-a关系,即父类和派生类在概念本质上应该是相同的。对于interface来说则不然,并不要求interface的实现者和interface定义在概念本质上是一致的, 仅仅是实现了interface定义的契约而已。为了使论述便于理解,下面将通过一个简单的实例进行说明。考虑这样一个例子,假设在我们的问题领域中有一个关于Door的抽象概念,该Door具有执行两个动作open和close,此时我们可以通过abstract class或者interface来定义一个表示该抽象概念的类型,定义方式分别如下所示:使用abstract class方式定义Door:abstract class Doorabstract void open();abstract void close();使用interface方式定义Door:interface Doorvoid open();void close();其他具体的Door类型可以extends使用abstract class方式定义的Door或者implements使用interface方式定义的Door。看起来好像使用abstract class和interface没有大的区别。如果现在要求Door还要具有报警的功能。我们该如何设计针对该例子的类结构呢(在本例中, 主要是为了展示 abstract class 和interface 反映在设计理念上的区别,其他方面无关的问题都做了简化或者忽略)?下面将罗列出可能的解 决方案,并从设计理念层面对这些不同的方案进行分析。解决方案一:简单的在Door的定义中增加一个alarm方法,如下:abstract class Doorabstract void open();abstract void close();abstract void alarm();或者interface Doorvoid open();void close();void alarm();那么具有报警功能的AlarmDoor的定义方式如下:class AlarmDoor extends Doorvoid open()void close()void alarm()或者class AlarmDoor implements Doorvoid open()void close()void alarm()这种方法违反了面向对象设计中的一个核心原则 ISP (Interface Segregation Principle),在Door的定义中把Door概念本身固有的行为方法和另外一个概念报警器的行为方 法混在了一起。这样引起的一个问题是那些仅仅依赖于Door这个概念的模块会因为报警器这个概念的改变(比如:修改alarm方法的参数)而改变,反 之依然。解决方案二:既然open、close和alarm属于两个不同的概念,根据ISP原则应该把它们分别定 义在代表这两个概念的抽象类中。定义方式有:这两个概念都使用 abstract class 方式定义;两个概念都使用interface方式定义;一个概念 使用 abstract class 方式定义,另一个概念使用interface方式定义。显然,由于Java语言不支持多重继承,所以两个概念都使用abstract class方式定义是不可行的。后面两种方式都是可行的,但是对于它们的选择却反映出对于问题领域中的概念本质的理解、对于设计意图的反映是否正确、合理。我们一一来分析、说明。如果两个概念都使用interface方式来定义,那么就反映出两个问题:1、我们可能没有 理解清楚问题领域,AlarmDoor在概念本质上到底是Door还是报警器?2、如果我们对于问题领域的理解没有问题,比如:我们通过对于问题领域的分 析发现AlarmDoor在概念本质上和Door是一致的,那么我们在实现时就没有能够正确的揭示我们的设计意图,因为在这两个概念的定义上(均使用 interface方式定义)反映不出上述含义。如果我们对于问题领域的理解是:AlarmDoor在概念本质上是Door,同时它有具有报 警的功能。我们该如何来设计、实现来明确的反映出我们的意思呢?前面已经说过,abstract class在Java语言中表示一种继承关系,而继承关系 在本质上是is-a关系。所以对于Door这个概念,我们应该使用abstarct class方式来定义。另外,AlarmDoor又具有报警功能,说 明它又能够完成报警概念中定义的行为,所以报警概念可以通过interface方式定义。如下所示:abstract class Doorabstract void open();abstract void close();interface Alarmvoid alarm();class Alarm Door extends Door implements Alarmvoid open()void close()void alarm()这种实现方式基本上能够明确的反映出我们对于问题领域的理解,正确的揭示我们的设计意图。其 实abstract class表示的是is-a关系,interface表示的是like-a关系,大家在选择时可以作为一个依据,当然这是建立在对问题领域的理解上的,比如:如果我们认为AlarmDoor在概念本质上是报警器,同时又具有Door的功能,那么上述的定义方式就要反过来了。(四)abstract class总结 1.abstract class通常含有一个或多个抽象方法,抽象方法不提供实现;包含抽象方法的类必须声明为抽象类abstract class;abstract class的所有具体子类都必须为超类提供具体实现;子类如果没有实现超类的抽象方法,则会产生编译错误,除非子类也声明为abstract。 2.abstract class声明了类层次结构中各个类的共同属性和行为;由于不能继承构造函数,因此构造函数不能声明为抽象方法;尽管不能实例化抽象类的对象,但是能够声明抽象类型的变量,这种变量可用于引用子类的对象(五
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 教师招聘之《小学教师招聘》全真模拟模拟题(a卷)附答案详解
- 2025年教师招聘之《小学教师招聘》试卷及答案详解(必刷)
- 2025年教师招聘之《幼儿教师招聘》考前冲刺练习题及答案详解(基础+提升)
- 教师招聘之《幼儿教师招聘》考前冲刺练习试题附答案详解(研优卷)
- 教师招聘之《幼儿教师招聘》强化训练模考卷及答案详解(全优)
- 教师招聘之《小学教师招聘》练习题(一)及参考答案详解【研优卷】
- 教师招聘之《小学教师招聘》通关考试题库含完整答案详解【夺冠系列】
- 教师招聘之《小学教师招聘》通关模拟题库完整版附答案详解
- 2025内蒙古呼伦贝尔农垦莫拐农牧场有限公司招聘16人考试备考附答案详解
- 教师招聘之《幼儿教师招聘》自测题库及参考答案详解(考试直接用)
- GB/T 45940-2025网络安全技术网络安全运维实施指南
- 2024年仙桃市高新技术产业投资有限公司招聘笔试真题
- 敦煌课件讲解稿子
- 2025年环境工程师初级职称考试试题及答案解析
- 眼科特检基础知识培训课件
- 统编版高中思想政治必修1第一课社会主义从空想到科学、从理论到实践的发展1.2科学社会主义的理论与实践 教学课件
- 摄影剪辑基本知识培训课件
- 北京高校标准化食堂标准(2026版)讲解
- 2025北京市交通发展年度报告
- 凿壁借光课文讲解
- 2025年全国招标采购专业技能大赛(地方组)历年参考题库含答案详解(5套)
评论
0/150
提交评论