您当前的位置: 首页 >  Java

慕晨sekurlsa

暂无认证

  • 5浏览

    0关注

    82博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

JAVA基础(十八)——多态

慕晨sekurlsa 发布时间:2022-08-15 23:09:50 ,浏览量:5

一、目录
  • 多态的介绍
  • 方法的多态
  • 对象的多态
  • 多态的细节
  • 动态绑定机制
  • 多态数组
  • 多态参数
二、多态的介绍

方法或对象具有多种形态。是面向对象的第三大特征,多态是建立在封装和继承的基础之上的。

多态分为方法的多态和对象的多态,其中对象的多态是多态的核心。

三、方法的多态

方法的多态体现在重写和重载上。也就是说,重写和重载都属于多态,它们都是多态的一种表现形式。

package com.javaploy;

public class Functionploy {
    public static void main(String[] args) {
        B b = new B();
        b.sum(1,2,3);
        b.sum(1,2);

        A a = new A();
        a.say();
        b.say();
    }
}

class A{
    public void say(){
        System.out.println("Class A is be used");
    }
}

class B extends A{
    public int sum(int a, int b, int c){
        return a + b + c;
    }
    
    public int sum(int a, int b){
        return a + b;
    }

    public void say(){
        System.out.println("Class B is be used");
    }
}

比如上面这段代码中,sum方法和say方法,就都体现了多态。

四、对象的多态

重要的几句话:

  1. 一个对象的编译类型和运行类型可以不一致。

    Animal animal = new Dog(); animal的编译类型是Animal,运行类型是Dog。

  2. 编译类型在定义对象时,就确定了,不能改变。但是运行类型是可以变化的。

    animal = new Cat(); 这时候,animal的编译类型还是Animal,但是运行类型已经变成了Cat。

  3. 编译类型看定义时,看=号的左边,运行类型看=号的右边。

例:

package com.javaploy.objectploy;

public class Animal {
    public void Cry(){
        System.out.println("Animal is Crying");
    }
}

class Dog extends Animal{

    public void Cry() {
        System.out.println("Dog is Crying");
    }
}

class Cat extends Animal{

    public void Cry() {
        System.out.println("Cat is Crying");
    }
}
package com.javaploy.objectploy;

public class PloyObject {
    public static void main(String[] args) {
        Animal animal = new Dog();
        animal.Cry();

        animal = new Cat();
        animal.Cry();
    }
}

输出结果为:

Dog is Crying
Cat is Crying

这里面,animal对象的编译类型一直是Animal,但是运行类型从Dog变成了Cat。

五、多态的细节
  • 多态的前提是:两个对象(类)存在继承关系

  • 多态的向上转型 关于向上转型:

    1. 本质:父类的引用指向了子类的对象
    2. 语法:父类类型 引用名 = new 子类类型();
    3. 特点:编译类型看左边,运行类型看右边。 可以调用父类中的所有成员(需遵守访问权限) 不能调用子类中的特有成员(因为虽然运行类型是子类,但是能不能调用某个类成员,是在编译阶段,由编译器决定的,它的编译类型是父类,父类中没有子类特有的那个属性或方法,所以调不了。但如果调用子类中重写父类的方法,是可以调的,因为编译的时候,编译器找到了这个类,然后找的时候,还是会先从子类开始找。那么如果现在就想调用子类特有的成员,就需要向下转型。例如Cat cat = (Cat) animal;)。
  • 多态的向下转型

    1. 语法:子类类型 引用名 = (子类类型) 父类引用;
    2. 只能强转父类的引用,不能强转父类的对象。
    3. 要求父类的引用必须指向的是当前目标类型的对象。

      这句话怎么理解? 比如: Animal animal = new Cat(); 这时候,父类的引用指向的对象是Cat。 Cat cat = (Cat) animal; //正确 Dog dog = (Dog) animal; //错误

    4. 当向下转型后,可以调用子类类型中所有的成员。
  • 调用属性,属性的值看编译类型。

  • instanceOf 比较操作符,用于判断对象的运行类型是否为XX类型或XX类型的子类型。

六、动态绑定机制
  • 动态绑定机制
    1. 当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定。
    2. 当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用。

看一段代码:

package com.javaDynamicBinging;

public class dynamicBanding {
    public static void main(String[] args) {
        A a = new B();
        System.out.println(a.sum());
        System.out.println(a.sum1());
    }
}


class A{
    public int i = 10;
    public int sum(){
        return getI() + 10;
    }

    public int sum1(){
        return i + 10;
    }

    public int getI(){
        return i;
    }
}

class B extends A{
    public int i = 20;
    public int sum(){
        return i + 20;
    }
    public int getI(){
        return i;
    }

    public int sum1(){
        return i + 10;
    }

}

上面这段代码,输出40和30。 如果把B类中的sum()方法去除,那么又会输出什么?

当B类中的sum()方法没有了之后,a.sum()自然而然的会去找其父类A的sum()方法。
结果发现里面又调用了getI()方法,这时候,由于B类和A类都有getI()方法,那么究竟调用哪一个?
这时候就用到了动态绑定机制,方法会和运行类型绑定,那么理所应当,调用B类中的getI()方法。
又因为属性不进行动态绑定,这时候方法在B类中,也就直接调用的B类的i的值。
所以输出30和30。
七、多态数组

多态数组:数组的定义类型为父类类型,里面保存的实际元素类型为子类类型。

比如有这样一道题目要求编写多态数组代码,创建一个Peroson父类,Student和Teacher子类。并将一个Person类对象和两个Student类对象以及两个Teacher类对象,一个五个元素同一放入数组中,并调用各自的say()方法。

package com.ployarr;

public class Javaployarr {
    public static void main(String[] args) {

        //这里创建了父类的数组,所有数组内可以放Person类,以及它的子类。
        Person[] persons = new Person[5];
        persons[0] = new Person("jack", 29);
        persons[1] = new Student("lilei", 12, 90);
        persons[2] = new Student("wang", 13, 92);
        persons[3] = new Teacher("Hong", 32, 10000);
        persons[4] = new Teacher("Bing", 30, 12000);

        //循环遍历多态数组
        for (int i = 0; i             
关注
打赏
1663680270
查看更多评论
0.0411s