定义: 某一类事物的多种存在方式(一个对象,两种形态)
对象的多态: 父类或者接口的引用指向其子类的对象
多态的好处:
提高了代码的扩展性,前期定义的代码可以使用后期的内容
多态弊端: 前期定义的内容不能使用(调用)后期子类的特有方法(就是多态调用的只能是父类)。但如果是继承子类覆盖了父类方法,多态调用的仍是子类的方法!
多态前提:
1、必须有关系(继承、实现)
2、要有覆盖
多态实际上是自动类型提升:
Animal a = new cat(); ( cat 型自动提升为 Animal 型(向上转型,得按 Animal 对象进行操作),因此 cat 只能调用 Anima 类中的方法,cat 中特有功能无法访问)。如果还想用猫的特有功能,可以强制向下转型:Cat c = (Cat) a。向下转型是为了使用特有方法。如果两者不具备继承关系不能强制转换!(向上转型为了提高扩展性并限制特有方法,向下转型为了使用特定方法)。对于转型自始至终都是子类对象做着类型的变化:
尽管 f 是指向 Zi()这个对象,但是实际运行依然是 Zi()这个对象调用方法。因此会先去方法区 Zi()这个空间中去找方法。若 ZI()方法区中没有则会去找 Fu()方法区,再去堆中找相对应的变量。若没有则在往上找,直到 Object 类。这其实就是_运行时多态,即到底运行 Fu()的方法还是 Zi()的方法等到程序运行时再去确定。_对于多态时的成员函数,总的来说分为三种情况:
_1、_父类有方法,子类有覆盖方法:编译通过,执行子类方法。
_2、_父类有方法,子类没覆盖方法:编译通过,执行父类方法(子类继承)。
_3、_父类没方法,子类有方法:编译失败,无法执行。
方法带 final、static、private 时是编译时多态**,**因为可以直接确定调用哪个方法。
覆盖与隐藏:
以下来自:https://www.cnblogs.com/it12345/p/5221673.html
隐藏 :child 隐藏了 parent 的变量和方法,那么,child 不能访问 parent 被隐藏的变量或者方法,但是,讲 B 转换成 A 中,可以访问 A 被隐藏的变量或者方法
覆盖 :child 覆盖了 parent 的变量或者方法,那么,child 不能访问 parent 被覆盖的变量或者方法,将 child 转换成 parent 后同样不能访问 parent 被覆盖的变量或者方法
首先看一下 JAVA 中方法和变量在继承时的覆盖和隐藏规则
-
父类的实例变量和静态变量能被子类的同名变量隐藏
-
父类的静态方法被子类的同名静态方法隐藏
-
父类的实例方法被子类的同名实例变量覆盖
还有几点需要注意的是:
-
不能用子类的静态方法隐藏 父类中同样标示(也就是返回值 名字 参数都一样)的实例方法
-
不能用子类的实例方法覆盖 父类中同样标示的静态方法
-
这点儿请注意,就是变量只会被隐藏 不会被覆盖 ,无论他是实例变量还是静态变量,而且,子类的静态变量可以隐藏 父类的实例变量,子类的实例变量可以隐藏 父类的静态变量
下图结果为 3 就是因为 zi 自动转换为 Fu 类,在 zi 这个实例的堆内存中找到 Fu 类 num 的值。覆盖只发生在函数上!
instance of:
格式:引用 instance of 类 / 接口
如果给 Animal 传入了一只狗但是 Animal 需要转换成猫,这是就会发生错误。因此需要使用 instance of 来判断传入的引用类型。instanceof 用于判断对象的具体类型,只能应用于引用数据类型判断。一般向下转型时加入 instance of 判断增强代码健壮性。
多态成员特点: