多态的概述
-
某一个事物,在不同时刻表现出来的不同状态。
-
举例:
猫可以是猫的类型。 猫 m=new 猫();
同时猫也是动物的一种,也可以把猫称为动物。
动物 d=new 猫();
在举一个例子:水在不同时刻的状态 -
多态前提和体现
有继承关系
有方法重写
有父类引用指向子类对象 -
多态中的成员访问特点:
A:成员变量:编译看左边,运行看左边;
B:构造方法:创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化;
C:成员方法:编译看左边,运行看右边;
D:静态方法:编译看左边,运行看左边; -
代码(成员变量):
package cn.manman.com;
class fu{
public int num=100;
}
class zi extends fu{
public int num2=1000;
public int num=20;
}
public class duotai {
public static void main(String[] args) {
fu f=new zi();
System.out.println(f.num);
System.out.println(f.num2);
}
}
这样是编译不成功的,因为多态的访问特点,看左边,是父类继承子类,这里f调用num2 的时候会报错(如下图),因为父类里面并没有num2这个变量;
报错图
package cn.manman.com;
class fu1{
public int num=100;
}
class zi1 extends fu1{
public int num2=1000;
public int num=20;
}
public class duotai {
public static void main(String[] args) {
fu1 f1=new zi1();
System.out.println(f1.num);
//System.out.println(f1.num2);
}
}
我现在将最后一行注释掉,运行结果如下:
image.png
- 代码(成员方法):
package cn.manman.com;
class fu1{
public int num=100;
public void show(){
System.out.println("show fu");
}
}
class zi1 extends fu1{
public int num2=1000;
public int num=20;
public void show(){
System.out.println("shou zi");
}
public void method(){
System.out.println("method zi");
}
}
public class duotai {
public static void main(String[] args) {
fu1 f1=new zi1();
System.out.println(f1.num);
//System.out.println(f1.num2);
f1.show();
f1.method();
}
}
这段代码其实和上面一样也是有错误的,因为父类里面是没有method方法的,所以编译是通不过的;
错误图示
package cn.manman.com;
class fu1{
public int num=100;
public void show(){
System.out.println("show fu");
}
}
class zi1 extends fu1{
public int num2=1000;
public int num=20;
public void show(){
System.out.println("shou zi");
}
public void method(){
System.out.println("method zi");
}
}
public class duotai {
public static void main(String[] args) {
fu1 f1=new zi1();
System.out.println(f1.num);
//System.out.println(f1.num2);
f1.show();
//f1.method();
}
}
但是我现在吧最后一行注释掉了,我们再来看看结果:
成员方法
结果是show zi,所以存在一个方法的重写;但是除了静态的方法:
package cn.manman.com;
class fu1{
public int num=100;
public void show(){
System.out.println("show fu");
}
public static void function(){
System.out.println("function fu");
}
}
class zi1 extends fu1{
public int num2=1000;
public int num=20;
public void show(){
System.out.println("shou zi");
}
public void method(){
System.out.println("method zi");
}
public static void function(){
System.out.println("function zi");
}
}
public class duotai {
public static void main(String[] args) {
fu1 f1=new zi1();
System.out.println(f1.num);
//System.out.println(f1.num2);
f1.show();
//f1.method();
f1.function();
}
}
静态方法
多态中的弊端
- 不能使用子类的功能,就上面的代码而言,如果我还是要用method方法,该怎么使用呢?
A:可以创建子类对象调用方法(可以,但是再创建一个对象,有时候是不合理的,太占内存了)
B:把父类的引用强制转换为子类的引用(又称为向下转型) - 对象间的转型问题:
向上转型:fu f=new zi();
向下转型:zi z=(zi) f;//要求f 是必须能转换为zi的。
package cn.manman.com;
class fu1{
public int num=100;
public void show(){
System.out.println("show fu");
}
public static void function(){
System.out.println("function fu");
}
}
class zi1 extends fu1{
public int num2=1000;
public int num=20;
public void show(){
System.out.println("shou zi");
}
public void method(){
System.out.println("method zi");
}
public static void function(){
System.out.println("function zi");
}
}
public class duotai {
public static void main(String[] args) {
fu1 f1=new zi1();
System.out.println(f1.num);
//System.out.println(f1.num2);
f1.show();
//f1.method();
f1.function();
zi1 z=(zi1)f1;
z.method();
}
}
转型
这样就可以访问method的方法了。
网友评论