面向对象的三个基本特征(多态)

来源:互联网 发布:linux 设置系统时区 编辑:程序博客网 时间:2024/05/20 17:25

多态应该是面向对象中最重要的一个性质了,前面写的封装与继承都是为他做准备的


什么是多态?

百度上的一种解释是:

允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式

发送消息就是函数调用

说实话我是没看懂。。。。。


还有一种解释:

多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。

多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。

多态有两种表现形式:重载和覆盖


还有一种:

多态是同一个行为具有多个不同表现形式或形态的能力。

多态就是同一个接口,使用不同的实例而执行不同操作,如图所示:



我自己的理解是:

多态:是子类继承了父类或者接口后,用重载和重写的方法来重新实现父类或接口中的方法

(个人观点,不对往指出)

一般,我们使用多态是为了避免在父类里大量重载引起代码臃肿且难于维护。

多态的优点

  • 1. 消除类型之间的耦合关系
  • 2. 可替换性
  • 3. 可扩充性
  • 4. 接口性
  • 5. 灵活性
  • 6. 简化性

多态存在的三个必要条件是

1.继承

2.重写

3.父类引用指向子类对象

Java中多态的实现方式:继承父类或接口进行方法重写,同一个类中进行方法重载。


我们先来看看重载

重载

重载(overloading) 是在一个类里面,方法名字一定相同,而参数不同。返回类型可以相同也可以不同。

每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表(即不同的参数,类型不同,数量不同都可以)

最常用的地方就是构造器的重载。


我们来看个例子

public class 重载 {public static double add(double a,double b){return a+b;}public static int add(int a,int b){return a+b;}public static double add(int a){return a;}public static int add(int a,double b){return 1;}public static int add(double a,int b){return 1;}public static void main(String argc[]){System.out.println("调用add(int,int)方法:"+add(1,2));System.out.println("调用add(double,double)方法:"+add(2.1,3.3));System.out.println("调用add(int)方法:"+add(1));}}
运行结果如下


重载规则

  • 被重载的方法必须改变参数列表(参数个数或类型或顺序不一样);
  • 被重载的方法可以改变返回类型;
  • 被重载的方法可以改变访问修饰符;
  • 被重载的方法可以声明新的或更广的检查异常;
  • 方法能够在同一个类中或者在一个子类中被重载。
  • 无法以返回值类型作为重载函数的区分标准。
重写

重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。外壳不变,核心重写!

重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。


我们看个例子:

class Animal{   public void move(){      System.out.println("动物可以移动");   }} class Dog extends Animal{   public void move(){//对父类方法的重写      System.out.println("狗可以跑和走");   }} public class TestDog{   public static void main(String args[]){      Animal a = new Animal(); // Animal 对象      Animal b = new Dog(); // Dog 对象      a.move();// 执行 Animal 类的方法      b.move();//执行 Dog 类的方法   }}
运行结果为:


在上面的例子中可以看到,尽管b属于Animal类型,但是它运行的是Dog类的move方法。

这是由于在编译阶段,只是检查参数的引用类型。

然而在运行时,Java虚拟机(JVM)指定对象的类型并且运行该对象的方法。

因此在上面的例子中,之所以能编译成功,是因为Animal类中存在move方法,然而运行时,运行的是特定对象的方法。


方法的重写规则

  • 参数列表必须完全与被重写方法的相同;
  • 返回类型必须完全与被重写方法的返回类型相同;
  • 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。
  • 父类的成员方法只能被它的子类重写。
  • 声明为final的方法不能被重写。
  • 声明为static的方法不能被重写,但是能够被再次声明。
  • 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
  • 子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法。
  • 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
  • 构造方法不能被重写。
  • 如果不能继承一个方法,则不能重写这个方法。
以上就是多态实现的两种主要方法