目录
前言
(1)数据类型:什么样的数据类型,决定了其在内存当中的存储形式。
(2)向上转型:子类的对象可以被父类所接受。
不同数据类型在计算机当中的存储形式
一,多态的定义。
多态是java学习当中的重点,其涉及到了java当中包括类与对象,继承,重写以及数据类型等知识。概括来讲,多态就是在创建对象时用父类的数据类型,构造器却使用了子类的。
public class Test { public static void main(String[] args) { A a = new B(); } } class A { } class B extends A{ }
原因:A类是父类,B类是子类,在堆中为子类开辟内存时会先为父类开辟内存,而此时数据类型为A的变量就可以调用A类当中的方法了(不能调用B类当中的,重写方法除外)。
二,多态代码调用的执行流程。
首先创建父类
public class A { public String name; public int age; public void run(){ System.out.println("A跑的很快"); } public void eat(int 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 Test { public static void main(String[] args) { A a = new B(); } }
虽然子类和父类都已经创建完成但因为其数据类型是A类,所以只能调用A类中的变量和方法。(包括二者公用的重写方法)
三,多态代码中的注意事项。
(1)子类对父类方法的重写
public class A { public String name; public int age; public void run(){ System.out.println("A跑的很快"); } public void eat(int 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跑的很快"); } }
其中run()方法被子类重写,则重写后的run()方法被子类和父类所共用。
(2)向上转型
public class C { public static void handler(A a){ System.out.println("c的输出为>"); } }
public class Test { public static void main(String[] args) { B b = new B(); C.handler(b); } }
子类的对象可以被父类的类型所接受------>父类的引用指向子类的对象
用static修饰类后,使用类的调用
传入B类型的b,给hanlder(A a)方法,虽然hanlder内规定的类型值为A,但方法可以被使用,不报错,原因是B类的b可以向上转型为A类
四,例题
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)); } }
public class D extends B{ }
public class C extends B{ }
public class B extends A{ public String Show(Object obj){ return "B and B"; } public String Show(A obj){ return "B and A"; } }
public class A { public String Show(D obj){ return "A and D"; } public String Show(A obj){ return "A and A"; } }
1.a1.show(b)
输出 A and A ,因为a1是A类型的A()对象,A是父类则没有将B类加载到堆内存,即使有B b = new B();但这也只是从新在堆内存中开辟的空间,a1无法调用到,则show()没有被重写
2.a1.show(c)
输出 A and A ,因为C类是B的子类,B是A的子类,C可以向上转型到A类。
3.a1.show(d)
输出 A and D,有直接的数据类型为D的作为参数。
4.a2.show(b)
输出 B and A ,虽然a2指向A类但Show(A obj)被子类重写,且b向上转型到A类。
5.a2.show(c)
输出 B and A ,父类方法被子类重写,且c向上转型到A类。
6.a2.show(d)
输出 A and D,有直接的数据类型为D的作为参数。
7.b.show(b)
输出 B and A ,父类方法被子类重写,且b向上转型到A类。
8.b.show(c)
输出 B and A ,父类方法被子类重写,且c向上转型到A类。
9.b.show(d)
输出 A and D,有直接的数据类型为D的作为参数。