Java多态

Java多态

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

1.继承:要有继承关系,子类继承父类
2.重写:子类要重写父类
3.父类引用指向子类对象

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。

      Animal a = new Cat();  // 向上转型  
      a.eat();               // 调用的是 Cat 的 eat
      Cat c = (Cat)a;        // 向下转型  
      c.work();        // 调用的是 Cat 的 work

虚函数

虚函数的存在是为了多态

Java中其实没有虚函数的概念,如果Java中不希望某个函数具有虚函数特性,可以加上final关键字变成非虚函数

1.在C++中虚函数的体现:

#include<iostream>
using namespace std;
class A
{
    public:
        void virtual FUN()
        {
            cout<<"FUN in A is called"<<endl;
        }
};

class B : public A
{
    public:
        void FUN()
        {
            cout<<"FUN in B is called"<<endl;
        }
};

int main()
{
    A a;
    B b;
    A *p;
    p = &a;
    p->FUN();
    p = &b;
    p->FUN();
    return 0;
}

运行结果:

FUN in A is called
FUN in B is called

可以试试将第6行的关键字virtual去掉试运行下,会发现,运行结果如下:

FUN in A is called
FUN in A is called

通过这个例子,可以看到虚函数的作用------实现多态。指向基类的指针在操作它的多态类对象时,会根据不同的类对象,调用其相应的函数,这个函数就是虚函数。

2.在Java中虚函数的体现:

package test;
 
/**
 * Created by ping on 2015/10/12.
 */
class A{
    public void FUN(){
        System.out.println("FUN in A is called");
    }
}
class B extends A{
    public void FUN(){
        System.out.println("FUN in B is called");
    }
}
public class VirtualTest {
 
    public static void main(String args[])  {
        A a = new A();
        B b = new B();
        A p;
 
        p = a;
        p.FUN();
        p = b;
        p.FUN();
    }
}

运行结果:

FUN in A is called
FUN in B is called

3.引用网上的说法:

C++ --------- Java

虚函数 -------- 普通函数
纯虚函数 -------- 抽象函数
抽象类 -------- 抽象类
虚基类 -------- 接口

多态的实现方式

方式一:重写(Override)

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

子类能够重写父类方法。

当子类对象调用重写的方法时,调用的是子类的方法,而不是父类中被重写的方法。

要想调用父类中被重写的方法,则必须使用关键字 super

重载(Overload)
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
最常用的地方就是构造器的重载。

请添加图片描述

方式二:接口

java中的接口类似于生活中的接口,就是一些方法特征的集合,但没有方法的实现

接口(英文:Interface),不能被实例化。

一个类通过继承接口的方式,从而来继承接口的抽象方法。
一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。

接口没有构造方法。

接口中所有的方法必须是抽象方法。

接口不能包含成员变量,除了 static 和 final 变量。

接口不是被类继承了,而是要被类实现。

接口支持多继承。

接口的特性:

1.接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。
2.接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。
3.接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。

抽象类与接口区别:

  1. 抽象类中的方法可以有方法体
  2. 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
  3. 一个类只能继承一个抽象类,而一个类却可以实现多个接口。
  4. 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),JDK 1.8 以后,接口里可以有静态方法和方法体了。

接口的声明:

Interface关键字用来声明一个接口。

接口的实现:

当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类

重写接口中声明的方法时,需要注意以下规则:

1.类在实现接口的方法时,不能抛出强制性异常,只能在接口中,或者继承接口的抽象类中抛出该强制性异常。
2.类在重写方法时要保持一致的方法名,并且应该保持相同或者相兼容的返回值类型。
3.如果实现接口的类是抽象类,那么就没必要实现该接口的方法。

最后,一个类只能继承一个类,但是能实现多个接口。

接口的多继承:

在Java中,类的多继承是不合法,但接口允许多继承。

在接口的多继承中extends关键字只需要使用一次,在其后跟着继承接口。

public interface Hockey extends Sports, Event

方法三:抽象类与抽象方法

抽象类

在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

在Java中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口

在Java语言中使用abstract class来定义抽象类。

/* 文件名 : AbstractDemo.java */
public class AbstractDemo
{
   public static void main(String [] args)
   {
      Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
      Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00)!!!!!!!!!!!!!!!!1;//抽象类对象引用**
 
      System.out.println("Call mailCheck using Salary reference --");
      s.mailCheck();
 
      System.out.println("\n Call mailCheck using Employee reference--");
      e.mailCheck();
    }
}

// Employee为抽象类

程序编译运行结果:

Constructing an Employee
Constructing an Employee
Call mailCheck using Salary reference –
Within mailCheck of Salary class
Mailing check to Mohd Mohtashim with salary 3600.0

Call mailCheck using Employee reference–
Within mailCheck of Salary class
Mailing check to John Adams with salary 2400.

抽象方法

如果你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法。

注意:

1.public abstract double computePay();//抽象函数没有函数体没有中括号,直接跟分号

2.如果一个类包含抽象方法,那么该类必须是抽象类。

3.任何子类必须重写父类的抽象方法,或者声明自身为抽象类。

总结

1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。

2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。

3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。

4. 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。

5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java多态指的是同一个方法名可以根据不同的对象调用出不同的行为。具体来说,多态是一种面向对象编程的特性,实现多态的方式主要有两种:方法重载和方法覆盖。方法重载指的是在一个类中定义多个同名方法,但这些方法有不同的参数列表,编译器会根据参数列表的不同选择合适的方法进行调用。方法覆盖指的是子类重写父类的方法,使得在使用父类对象调用该方法时,实际调用的是子类中的方法。 多态的好处在于,它可以提高代码的灵活性和可扩展性。通过多态,我们可以为不同的对象提供不同的行为,从而使得程序更加具有扩展性。此外,多态还可以让程序的调用更加简洁、清晰,提高了代码的可读性和可维护性。 下面是一个简单的Java多态的例子: ```Java class Animal { public void makeSound() { System.out.println("动物发出声音"); } } class Cat extends Animal { public void makeSound() { System.out.println("猫发出“喵喵”的声音"); } } class Dog extends Animal { public void makeSound() { System.out.println("狗发出“汪汪”的声音"); } } public class PolymorphismExample { public static void main(String[] args) { Animal animal1 = new Animal(); Animal animal2 = new Cat(); Animal animal3 = new Dog(); animal1.makeSound(); // 动物发出声音 animal2.makeSound(); // 猫发出“喵喵”的声音 animal3.makeSound(); // 狗发出“汪汪”的声音 } } ``` 在上面的例子中,Animal是一个父类,Cat和Dog是Animal的子类。Animal类中定义了一个makeSound()方法,Cat和Dog类分别重写了这个方法。在main()方法中,我们创建了三个Animal类型的对象,并分别调用它们的makeSound()方法。由于animal2和animal3都是Animal类型的对象,但实际上它们分别是Cat和Dog类型的对象,因此在调用它们的makeSound()方法时,实际上是调用了它们各自的实现,也就是Cat类和Dog类中重写的makeSound()方法。这就是Java多态的表现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值