面向对象编程---多态

多【多种】态【状态】基本介绍:

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

多态的具体体现

  1. 方法的多态,重写和重载就体现方法的多态。
  2. 对象的多态(核心,困难,重点)

具体介绍如下:

  • 方法的多态,重写和重载就体现方法的多态。

package ploy_;

public class PloyMethod {
	public static void main(String[] args) {
		BBB b = new BBB();
		//方法重载体现多态
		//当形参列表参数个数/参数类型不同时,调用不同的sum方法,就体现多态了
		System.out.println(b.sum(1, 2));//3
		System.out.println(b.sum(1, 2, 3));//6
		System.out.println(b.sum(333.333, 333.333));//666.666
		
		AAA a = new AAA();
		//方法重写体现多态
		//父子类之间不同的对象调用不同的say()方法,就体现了多态
		a.say();//AAA的say()方法被调用了
		b.say();//BBB的say()方法被调用了
	}
}
class AAA{
	public void say() {
		System.out.println("AAA的say()方法被调用了");
	}
}
class BBB extends AAA {
	public int sum(int n,int m) {
		return n + m;
	}
	public int sum(int m,int n,int x) {
		return m + n + x;
	}
	public double sum(double m,double n) {
		return m + n;
	}
	public void say() {
		System.out.println("BBB的say()方法被调用了");
	}
}
  • 对象的多态(核心,困难,重点)

  1. 一个对象的编译类型和运行类型可以不一致
  2. 编译类型在定义对象时,就确定了,不能改变
  3. 运行类型是可以变化的
  4. 编译类型看定义时 =号 的左边,运行类型看 =号 的右边

        案例【其中Dog类、Cat类为Animal类的子类】:

Animal animal = new Animal();//animal编译类型是Animal,运行类型是Animal
Animal animal1 = new Dog();//animal1编译类型是Animal,运行类型是Dog
Animal animal2 = new Cat();//animal2编译类型是Animal,运行类型是Cat

     题外话,你看它像什么:

A.哈士羊        B.灰太羊        C.喜狼狼        D喜之郎

以上都是不对滴答案~~~,这是一只披着羊皮的狼,

它非常像我们上文提及的编译类型和运行类型的概念,从表面上看它是一只羊,但它骨子里是一只狼,一旦它运行(工作)起来是要吃羊的,羊就类似它的编译类型,运行起来就是一只狼,编译类型是编译器看到的类型,运行类型是JVM在真正执行的时候的类型。

  • 多态注意事项和细节讨论:

    • 多态的前提是:两个对象(类)存在继承关系
    • 多态的向上转型
    • 多态的向下转型
    • 属性没有重写之说!属性的值看编译类型
    • instanceOf比较操作符,用于判断对象的运行类型是否为XXX类型或XXX类型的子类型
  • 多态的向上转型

    • 本质:父类的引用指向了子类的对象
    • 语法:父类类型 引用名 = new 子类类型();
    • 特点:编译类型看左边,运行类型看右边。

        向上转型调用方法的规则如下:

  1. 可以调用父类中的所有成员(需遵守访问权限)
  2. 不能调用子类中特有成员;(因为在编译阶段,能调用哪些成员,是由编译类型来决定的)
  3. 最终运行效果看子类(运行类型)的具体实现!(即调用方法时,按照从子类(运行类型)开始查找方法,然后调用,查找关系与之前子类调用方法/访问属性建立的查找关系相同)。因为编译时是javac编译器将我们写的代码(.java)文件翻译成JVM能识别的(.class)文件,而运行是由JVM执行的。

        编译:将代码(.java)文件交给编译器进行语法检查,没有语法错误就生成JVM能识别的字节码(.class)文件。

        运行:将字节码(.class)文件交给JVM执行,如果没有逻辑错误,就会出现运行结果。

  • 多态的向下转型

    • 语法:子类类型 引用名 = (子类类型)父类引用;
    • 只能强转父类的引用,不能强转父类的对象。
    • 要求父类的引用必须指向的是当前目标类型的对象。
      Animal animal = new Cat();//向上转型,animal引用指向Cat对象
      Cat cat = (Cat)animal;//向下转型,
      //因为animal引用指向的是Cat对象,
      //所以才可以将animal转成Cat类型
      //Dog dog = (Dog)animal;///不可以,
      //因为animal引用指向的是Cat对象,猫是动物,狗是动物,
      //但不能说 动物是猫 或 动物是狗,也不能说 猫是狗 或 狗是猫。
    • 当向下转型后,可以调用子类类型中所有的成员
  • 属性没有重写之说!属性的值看编译类型

public class PolyAttribute {
    public static void main(String[] args) {
        Food food = new Food();
        Food food1 = new Bond();
        Food food2 = new Rice();
        System.out.println(food.name);//食物
        System.out.println(food1.name);//食物
        System.out.println(food2.name);//食物
        Bond bond = new Bond();
        Rice rice = new Rice();
        System.out.println(bond.name);//骨头
        System.out.println(rice.name);//米饭
    }
}
class Food{
    public String name = "食物";
}
class Bond extends Food {
    public String name = "骨头";
}
class Rice extends Food {
    public String name = "米饭";
}
  • instanceOf比较操作符,用于判断对象的运行类型是否为XXX类型或XXX类型的子类型

public class PolyDetails01 {
    public static void main(String[] args) {
        AA aa = new AA();
        BB bb = new BB();
        System.out.println(aa instanceof AA);//true
        System.out.println(bb instanceof BB);//true
        System.out.println(bb instanceof AA);//true

        //编译类型AA,运行类型BB
        AA ab = new BB();
        System.out.println(ab instanceof AA);//true
        System.out.println(ab instanceof BB);//true
        System.out.println(aa instanceof BB);//false
    }
}
class AA{}
class BB extends AA{}

小小建议:这部分不是很理解的可以去看看我的另一篇博文《类和对象的内存分配机制》,在理解对象创建的内存机制后再看这里的多态,就会更容易理解编译类型和运行类型的问题了。

  • 10
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值