Java 多态
Posted 守林鸟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 多态相关的知识,希望对你有一定的参考价值。
多态:一个对象有多种形态
- 是方法的多态,和属性无关
- 有继承关系、重写方法、父类引用 指向 子类对象
- 静态方法不支持多态
举例,
有父类Dog,属性name="dog",普通方法say,静态方法move;
子类SDog,属性name="sdog",重写了普通方法say,重写了静态方法move,另外有自己的普通方法sd;
子类BDog,属性name="bdog",重写了普通方法say,重写了静态方法move,另外有自己的方法bd;
孙类SDog_son继承了SDog,属性name="sdog_son",重写了普通方法say,重写了静态方法move;
测试代码:
package my_test; public class Main { public static void main(String[] args) { Dog d1;//d1是一个引用 d1=new Dog();//d1 指向父类Dog创建的对象 d1.say(); d1.move(); System.out.println(d1.name); System.out.println("------------------------------------------"); d1=new SDog();//d1 指向子类SDog创建的对象,上面失去引用的对象会被回收 d1.say(); d1.move(); System.out.println(d1.name); System.out.println("------------------------------------------"); //d1.sd();//报错,因为Dog中没有sd()方法.The method sd() is undefined for the type Dog d1=new BDog(); d1.say(); d1.move(); System.out.println(d1.name); //d1.bd();//报错,同上 System.out.println("------------------------------------------"); d1=new SDog_son();//d1 指向孙类SDog_son创建的对象,上面失去引用的SDog对象会被回收 d1.say(); d1.move(); System.out.println(d1.name); System.out.println("------------------------------------------"); } } class Dog { String name="dog"; public void say() { System.out.println("dog_say"); } public static void move() { System.out.println("dog_move"); } } class SDog extends Dog{ String name="sdog"; public void say() { System.out.println("sdog_say"); } public static void move() { System.out.println("sdog_move"); } public void sd() { System.out.println("sdog自己独特的方法sd"); } } class BDog extends Dog{ String name="bdog"; public void say() { System.out.println("bdog_say"); } public static void move() { System.out.println("bdog_move"); } public void bd() { System.out.println("bdog自己独特的方法bd"); } } class SDog_son extends SDog{ String name="sdog_son"; public void say() { System.out.println("sdog_son_say"); } public static void move() { System.out.println("sdog_son_move"); } } class Factory{//没有报错,将用于工厂方法模式 public Dog createdog(int id) { if(id==1) return new Dog(); else if(id==2) return new SDog(); else return new BDog(); } }
输出:
dog_say
dog_move
dog
------------------------------------------
sdog_say
dog_move
dog
------------------------------------------
bdog_say
dog_move
dog
------------------------------------------
sdog_son_say
dog_move
dog
------------------------------------------
Dog的引用 指向 不同的子孙类对象的各种情况下:
1.调用普通方法say,输出是各自子孙类的重写方法,并且调用子类自己的方法sd()和bd()会报错。验证:继承的重写方法 支持多态
2.调用静态方法move,输出的都是父类的静态方法内容。验证:静态方法不支持多态
3.System.out.println(d1.name);输出的都是dog。验证:多态和属性无关
另附一些理解:
1.d1这个变量是引用,放在内存栈里。new出来的东西放在内存堆里,引用即栈指向堆。
2.编译时多态(也称静态多态,也就是调用静态方法的多态),因为编译时就加载了静态的代码块,存在静态常量池里。
3.运行时多态(也就是通常说的多态,因为大家都觉得静态方法不支持多态,实际上只是没体现出来,而我们需要解决的问题是通过运行时多态解决的,所以我们说的多态都是运行时多态),编译时不确定究竟调用哪个具体方法,一直延迟到运行时才能确定。(多态方法又被称为延迟方法的原因)。实现技术叫:动态绑定。编译时只加载静态代码,运行时才加载普通代码,当类被载入到虚拟机内部的时候,在内存中产生类的常量池叫运行时常量池。
4.静态方法可以通过类名调用,不妨理解为:d1是Dog的变量,调用静态方式是通过类调用,即d1.move()就是Dog.move()
以上是关于Java 多态的主要内容,如果未能解决你的问题,请参考以下文章