全部博文(247)
分类: Java
2014-11-08 09:50:07
所谓多态,就是父类型的引用可以指向子类型的对象,或者接口类型的引用可以指向实现该接口的类的实例。
多态性是指统一的接口,不同的表现形式。
多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。
多态有两种表现形式:重载和覆盖
首先说重载(overload),是发生在同一类中。与什么父类子类、继承毫无关系。标识一个函数除了函数名外,还有函数的参数(个数和类型)。也就是说,一个类中可以有两个或更多的函数,叫同一个名字而他们的参数不同。他们之间毫无关系,是不同的函数,只是可能他们的功能类似,所以才命名一样,增加可读性,仅此而已!
再说覆盖(override),是发生在子类中!也就是说必须有继承的情况下才有覆盖发生。我们知道继承一个类,也就有了父类了全部方法,如果你感到哪个方法不爽,功能要变,那就把那个函数在子类中重新实现一遍。这样再调用这个方法的时候,就是执行子类中的过程了。父类中的函数就被覆盖了。(当然,覆盖的时候函数名和参数要和父类中完全一样,不然你的方法对父类中的方法就不起任何作用,因为两者是两个函数,毫不关系)
override(重写,覆盖)
1、方法名、参数、返回值相同。
2、子类方法不能缩小父类方法的访问权限。
3、子类方法不能抛出比父类方法更多的异常(但子类方法可以不抛出异常)。
4、存在于父类和子类之间。
5、方法被定义为final不能被重写。
overload(重载,过载)
1、参数类型、个数、顺序至少有一个不相同。
2、不能重载只有返回值不同的方法名。
3、存在于父类和子类、同类中。
方法的重写(Overriding)和重载(Overloading)是Java多态性的不同表现。
重写(Overriding)是父类与子类之间多态性的一种表现,而重载(Overloading)是一个类中多态性的一种表现。
如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被"屏蔽"了.
如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型或有不同的参数次序,则称为方法的重载(Overloading)。不能通过访问权限、返回类型、抛出的异常进行重载.
1. Override 特点
1、覆盖的方法的标志必须要和被覆盖的方法的标志完全匹配,才能达到覆盖的效果;
2、覆盖的方法的返回值必须和被覆盖的方法的返回一致;
3、覆盖的方法所抛出的异常必须和被覆盖方法的所抛出的异常一致,或者是其子类;
4、被覆盖的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行覆盖。
2.Overload 特点
1、在使用重载时只能通过不同的参数样式。例如,不同的参数类型,不同的参数个数,不同的参数顺序(当然,同一方法内的几个参数类型必须不一样,例如可以是fun(int, float), 但是不能为fun(int, int));
2、不能通过访问权限、返回类型、抛出的异常进行重载;
3、方法的异常类型和数目不会对重载造成影响;
4、对于继承来说,如果某一方法在父类中是访问权限是priavte,那么就不能在子类对其进行重载,如果定义的话,也只是定义了一个新方法,而不会达到重载的效果。
关于接口与实现接口的类之间的强制类型转换方式与父类和子类之间的强制类型转换方式完全一样。
用关键字abstract修饰的类叫做抽象类,抽象类不能被实例化,即不能new出来一个抽象类的对象(实例)。
用abstract关键字所修饰的方法叫做抽象方法。
抽象方法必须定义在抽象类中。
抽象方法有声明,无实现(没有花括号{},有花括号但是内容为空也是一种实现,空实现)。
相对应的有声明有实现的方法可以叫做具体方法。
抽象方法必须定义在抽象类里面。
如果一个类包含了抽象方法,那么这个类一定要声明成抽象类。
如果某个类是抽象类,那么这个类既可以包含抽象方法,也可以包含具体的方法(有声明,有实现)。
抽象类中如果全是具体方法也是允许的;抽象类也可以是空的,即什么也不包含。
在父类是一个抽象类的情况下,子类继承父类时,有两种选择:
1.子类是抽象类
那么子类在声明时仍然需要abstract关键字,子类可以选择实现或者不实现父类的抽象方法,(因为抽象类中也可以包括具体方法,甚至可以全是具体方法)。
但是无论怎样,因为子类还是一个抽象类,所以不能实例化。
2.子类不是抽象类
子类不是抽象类时可实例化,但是这时候子类必须实现父类所有的抽象方法。
实现抽象方法的时候不必再使用abstract关键字。
抽象类的抽象方法定义一个规范,或者叫做约定,具体实现交给子类来做。
因为抽象类的实现可能无法完成或者没有意义。
举个例子:
定义一个抽象类Shape,然后Triangle,Circle和Rectangle等继承Shape,Shape中定义一个抽象方法计算面积,然后各个子类中实现这个方法,计算各自的面积。
这时候如果不用抽象类和抽象方法,即Shape类是一个普通的类,也可以完成这样的功能,即通过用子类方法覆盖父类方法的方式。
但是此时父类,即Shape中的方法就要提供具体的实现,首先不知道怎么计算这个抽象的形状的面积,如果父类面积定义一个常数,如0或1,又显得意义不明晰。
接口用关键字interface声明。
接口的地位等同于class,接口中的所有方法都是抽象方法。
接口中在定义方法的时候,可以使用abstract关键字,也可以省略abstract关键字,(大多数时候都是省略的),方法仍是抽象的,不能有实现的花括号。
接口和抽象类的功能类似,接口也不能实例化,可以将接口看作是一种特殊的抽象类(全是抽象方法)。
接口的多态用法和抽象类也类似,接口类型的引用可以指向实现了这个接口的类的对象。
接口和抽象类的区别如下:
接口中的方法必须全是抽象方法;而抽象类中的方法,可以有抽象的,也可以有具体的方法。
类可以实现接口,用关键字implements。Java是单继承的,但是却可以实现多个接口。(一个类可以同时继承另一个类,并且实现多个接口。)
如果一个类实现了一个接口,并且这个类不是抽象类,那么这个类必须实现这个接口中的所有方法。如果是抽象类,则无需实现接口中的所有方法。