多态是什么
多态指的是父类的引用指向了子类的对象。
public class A{
}
public class B extends A{
}
public static void main(String[] args) {
A ab =new B();
}
上述代码就是多态的体现,变量ab的存储方式是A类型,但是变量ab却是B类的对象。
多态的用法
介绍
多态的用法为向上继承,向上继承的过程是Java自动执行的。
下面,以一个例子介绍多态。
首先,创建A类。
public class A{
public String name;
public int age;
public void run(){
System.out.println("A跑得很快");
}
public void eat(String name){
System.out.println(name+"吃得多");
}
}
接着,创建B类,B类继承A类。
public class B extends A{
}
在main方法中创建三个变量。
public static void main(String[] args) {
A ab =new B();
A a =new A();
B b=new B();
}
此时,变量a和变量b的存储形式如下:
变量a
变量b
将B类的代码优化一下:
public class B extends A{
public char sex;
public double height;
public void flay(){
System.out.println("B飞得高");
}
public void run(){
System.out.println("B跑得很快");
}
}
此时b的存储结构为:
ab的存储结构为:
分析
ab是B类创造的对象,但是存储方式为A类,所以ab的模板其实是A类,即属性为A类的属性,方法为A类的方法,但是由于B继承A后重写run方法,导致由B类创建的对象的run方法已被覆盖,ab调用的就是B类重写后的方法,但是ab不能调用B类的其他方法。
向上转型
这是已经创建好的两个类:
public class A{
public String name;
public int age;
public void run(){
System.out.println("A跑得很快");
}
public void eat(String name){
System.out.println(name+"吃得多");
}
}
public class B extends A{
public char sex;
public double height;
public void flay(){
System.out.println("B飞得高");
}
public void run(){
System.out.println("B跑得很快");
}
}
再创键第三个类:
public class C{
public static void hanlder(A a){
System.out.println("C的输出");
}
}
在main方法中调用C中方法:
public static void main(String[] args){
B b =new B();
C.hanlder(b);
}
此时代码不会出现报错,这就是向上转型,由Java自动完成。
向上转型的意思为子类的对象可以被父类的类型所接受-->父类的引用指向了子类的对象。
更通俗点讲,子类的对象可以作为参数进入只接受其父类参数的方法中(我个人的理解为替父从军、子承父业)。
以例子分析多态的运行思路
引入一个例子:
public class A {
public String show(D obj) {
return ("A and D");
}
public String show(A obj) {
return ("A and A");
}
}
public class B extends A{
public String show(B obj){
return ("B and B");
}
public String show(A obj){
return ("B and A");
}
}
public class C extends B{
}
public class D extends B{
}
public class Test {
public static void main(String[] args) {
A a1 = new A();
A a2 = new B();
B b = new B();
C c = new C();
D d = new D();
System.out.println("1--" + a1.show(b));
System.out.println("2--" + a1.show(c));
System.out.println("3--" + a1.show(d));
System.out.println("4--" + a2.show(b));
System.out.println("5--" + a2.show(c));
System.out.println("6--" + a2.show(d));
System.out.println("7--" + b.show(b));
System.out.println("8--" + b.show(c));
System.out.println("9--" + b.show(d));
}
}
输出为:
1--A and A
2--A and A
3--A and D
4--B and A
5--B and A
6--A and D
7--B and B
8--B and B
9--A and D
分析:
1~3:
a1为A类创建的对象,存储方式为A类。
1、传参为b,b是B类创建的对象,B类继承A类,b可以作为参数传入需要参数为A类对象的方法中,即调用a1.show(b)其实是调用show(A obj),输出结果为:A and A。
2、传参为c,c是C类创建的对象,C类继承B类,B类继承A类,c可以作为参数传入需要参数为A类对象的方法中,即调用a1.show(c)其实是调用show(A obj),输出结果为:A and A。
3、传参为d,d是D类创建的对象,A类中有show(D obj) 方法,即调用a1.show(d)其实是调用show(D obj),输出结果为:A and D。
4~6:
a2为B类创建的对象,存储方式为A类。
4、传参为b,b是B类创建的对象,B类继承A类,b可以作为参数传入需要参数为A类对象的方法中,即调用a2.show(b)其实是调用show(A obj),但是由于a2是B类创造的对象,B类中又对show(A obj)方法进行了重写,所以调用a2.show(b)其实是调用B类中的方法show(A obj),输出结果为:B and A。
5、传参为c,c是C类创建的对象,C类继承B类,B类继承A类,c可以作为参数传入需要参数为A类对象的方法中,即调用a2.show(c)其实是调用show(A obj),但是由于a2是B类创造的对象,B类中又对show(A obj)方法进行了重写,所以调用a2.show(c)其实是调用B类中的方法show(A obj),输出结果为:B and A。
6、传参为d,d是D类创建的对象,A类中有show(D obj) 方法,即调用a2.show(d)其实是调用show(D obj),输出结果为:A and D、
7~9:
b为B类创造的对象,存储方式为B类。
7、传参为b,b是B类创建的对象,调用b.show(b)其实是调用B类中的show(B obj),输出结果为:B and B。
8、传参为c,c是C类创建的对象,C类继承B类,c可以作为参数传入需要参数为B类对象的方法中,即调用b.show(c)其实是调用show(B obj),输出结果为:B and B。
9、传参为d,d是D类创建的对象,A类中有show(D obj) 方法,b作为B类创建的对象,B类继承A类,即作为子类对象的b可以调用父类方法,即调用b.show(d)其实是调用B类父类中的show(D obj),输出结果为:A and D。
到此,全篇文章结束。