在面向对象的程序设计语言中,多态是继数据抽象和继承之后的第三种基本特征(——Java编程思想)
数据抽象,即封装,通过合并特征和行为来创建新的数据类型,通过将细节“私有化”将接口和实现分离。
继承,允许将对象视为它自己本身的类型或者其基类型来处理,从同一基类导出的多种类型均可以视为一种类型来处理。
多态(又称动态绑定、后期绑定、运行时绑定)同样是将接口和实现分离,不过是通过分离做什么和怎么做来实现的。既能改善代码的组织结构和可读性,还能创建可扩展的程序。
了解多态,首先有必要研究一下以下几个概念。
1.方法绑定:一个方法被调用时该方法关联其方法体的过程。
2.静态绑定:在面向过程的中又称为前期绑定在程序编译时进行了绑定,即在还没运行时,就已经加载到内存。
3.动态绑定:在面向过程中称为后期绑定(运行时绑定)在运行时就进行绑定,根据实际情况有选择的进行绑定
Java中除了static方法和final方法(private方法属于static方法)之外,其他所有的方法都属于后期绑定。所以,在Java中,在没有前面所提到的几个关键词修饰的情况下,默认的绑定方式为后期绑定。
通过代码介绍
public class Bird {
public void fly(){
System.out.println("Bird Fly");
}
}
public class Dove extends Bird{
public void fly(){
System.out.println("Fly with Olive Branch");//覆盖父类方法
}
}
public class BirdFly {
public static void main(String[] args) {
Bird bird1 = new Dove();//向上转型
bird1.fly();
}
}
运行结果是:Fly with Olive Branch
向上转型后,父类也只能调用父类已经有的方法”。但是子类如果覆盖了父类的方法,那么即使向上转型,方法的行为也表现为覆盖后的行为。这也是多态的一种体现。向上转型更多的用来体现一种编程上的“约定”。所有继承某个类或者实现某个接口的类,一定包含某个方法,这样在调用的时候,使得你也不必关系具体的实现细节,只要知道“这个类型中的某个方法能帮我完成工作”就可以了。
向下转型是“引用的类型”的变化,不是对象实例类型的变化。new什么,就是什么。不会因为向上或者向下转型而改变自己的类型。
除了代码的复用性外,多态还可以解决项目中紧偶合的问题,提高程序的可扩展性.。耦合度讲的是模块模块之间,代码代码之间的关联度,通过对系统的分析把系统分解成一个个子模块,子模块提供稳定的接口,达到降低系统耦合度的的目的,模块模块之间尽量使用接口访问,而不是随意引用其他模块的成员变量。
1. 应用程序不必为每一个派生类编写功能调用,只需要对抽象基类进行处理即可。只和基类打交道,大大提高程序的可复用性。//继承
2. 派生类的功能可以被基类的方法或引用变量所调用,这叫向后兼容,可以提高可扩充性和可维护性。 //多态的真正作用
实现多态的方式最常用的就是重写、重载以及接口实现
父类与子类直接的多态用重写实现
代码示例可以看上文中BirdFly的例子
重写的规则:
1、参数列表必须完全与被重写的方法相同,否则不能称其为重写而是重载。
2、返回的类型必须一直与被重写的方法的返回类型相同,否则不能称其为重写而是重载。
3、访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private)
4、重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常。例如:
父类的一个方法申明了一个检查异常IOException,在重写这个方法是就不能抛出Exception,只能抛出IOException的子类异常,可以抛出非检查异常。
类内的多态用重载实现
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();
}
}
个人觉得,接口的实现,都是多态的
欢迎各位讨论指教