Java(十九)多态

25 阅读3分钟

多态,面向对象的三大特征之一。

那么,什么是多态呢?

多态是指一个对象在不同的时刻,表现出来的不同的状态。

 

一:多态的基本使用

多态的前提条件:

1:要有继承关系

2:要有方法的重写

3:要有父类引用指向子类对象

上一段代码:

public class T02 {
    public static void main(String[] args) {
        // 父类引用指向子类对象
        fu fu = new zi();
        fu.print();// 子类
    }
}
/**
 * 父类
 */
class fu
{
    public void print()
    {
        System.out.println("父类");
    }
}
 
/**
 * 子类
 */
class zi extends fu
{// 有继承关系
    @Override // 有方法重写
    public void print()
    {
        System.out.println("子类");
    }
}

输出:

子类

 

二:多态间子父类之间成员变量的关系

public class T02 {
    public static void main(String[] args) {
        // 父类引用指向子类对象
        fu fu = new zi();
        // fu.print();// 子类
        System.out.println(fu.i); // 输出 1
        // =================================================
        // 这行代码编译报错
        // System.out.println(fu.j);
    }
}
/**
 * 父类
 */
class fu
{
    public int i = 1;
    public void print()
    {
        System.out.println("父类");
    }
}
 
/**
 * 子类
 */
class zi extends fu
{// 有继承关系
    public int j = 2;
    public int i = 4;
    @Override // 有方法重写
    public void print()
    {
        System.out.println("子类");
    }
}

输出:

1

 

通过上边的运行结果分析,父类引用不能使用子类中特有的成员变量

父类和子类中相同名字的成员变量调用的是父类的成员变量。

总结一句口诀:

多态调用成员变量的时候,编译看左边,运行看左边。

 

三:多态间子父类之间成员方法的关系

父类中有一个成员方法,子类中有一个与父类同名的成员方法,以及一个独有的成员方法。

如下方代码所示:

public class T02 {
    public static void main(String[] args) {
        // 父类引用指向子类对象
        fu fu = new zi();
        fu.print();// 子类
        // ==============================================
        // 这行代码编译报错
        // fu.printSP();
    }
}
/**
 * 父类
 */
class fu
{
    public int i = 1;
    public void print()
    {
        System.out.println("父类");
    }
}
 
/**
 * 子类
 */
class zi extends fu
{// 有继承关系
    public int j = 2;
    public int i = 4;
    @Override // 有方法重写
    public void print()
    {
        System.out.println("子类");
    }
    public void printSP()
    {
        System.out.println("子类独有的方法");
    }
}

输出:

子类

 

通过结果分析,父类引用可以使用子类中重写父类的方法。

总结一句口诀:

多态调用成员方法,编译看左边,运行看右边

 

四:多态间子父类之间静态成员方法的关系

public class T02 {
    public static void main(String[] args) {
        // 父类引用指向子类对象
        fu fu = new zi();
        fu.print();// 父类
    }
}
/**
 * 父类
 */
class fu
{
    public int i = 1;
    public static void print()
    {
        System.out.println("父类");
    }
}
 
/**
 * 子类
 */
class zi extends fu
{// 有继承关系
    public int j = 2;
    public int i = 4;
    public static void print()
    {
        System.out.println("子类");
    }
}

输出:

父类

 

总结一句口诀:

多态,静态,成员变量和成员方法,编译看左边,运行看左边。

其实,静态方法这个已经脱离了类的多态的范畴了。只要类加载,他就存储在内存中了。

 

五:多态的弊端

父类引用不能使用子类中特有的内容。

但是呢,这个好像是不太行啊,我们怎么处理这个问题呢?

我们可以通过向下转型来解决这个问题。

1:向上转换:

Fu fu = new zi();

 

2:向上转换:

Zi zi = (Zi)fu;

注意:向下转型转不好容易出现异常:ClassCastException类型转换异常,是在运行的时候报错。

下边使用代码举一个报错的例子:

package d0419;
 
public class T02 {
    public static void main(String[] args) {
        // 父类引用指向子类对象
        person fu = new teacher();
        fu.print();// 教师类
        // ========================================
        // 这行代码报错
        // fu.printSP();
 
        // ========================================
        // 正确的向下转换
        teacher tea = (teacher)fu;
        tea.printSP();
 
        // ========================================
        // 错误的向下转换
        student stu = (student)fu;
        stu.printSP();
    }
}
/**
 * 父类
 */
class person
{
    public void print()
    {
        System.out.println("父类");
    }
}
 
/**
 * 教师类
 */
class teacher extends person
{// 有继承关系
    public void print()
    {
        System.out.println("教师类");
    }
 
    public void printSP()
    {
        System.out.println("教师类特有方法");
    }
}
 
/**
 * 学生类
 */
class student extends person
{// 有继承关系
    public void print()
    {
        System.out.println("学生类");
    }
    public void printSP()
    {
        System.out.println("学生类特有方法");
    }
}

输出:

教师类
教师类特有方法
Exception in thread "main" java.lang.ClassCastException: d0419.teacher cannot be cast to d0419.student
        at d0419.T02.main(T02.java:19)

 

以上大概就是 java多态的基本使用。

 

有好的建议,请在下方输入你的评论。