Java的多态浅谈

简介: Java的多态浅谈概述Java的四大基本特性:抽象,封装,继承和多态。其中,抽象,封装,继承可以说多态的基础,而多态是封装,继承的具体表现。如果非要用专业术语来描述什么是多态的话多态是指程序中定义的引用变量所指向具体类型和通过该引用变量发出的方法调用在编译的时候并不确定,而是程序运行期间才确定,就是说一个引用变量到底指向哪一个类的实例对象,该引用变量发出的方法调用哪一个类的中的方法,必须在程序运行期间才能确定。

Java的多态浅谈
概述
Java的四大基本特性:抽象,封装,继承和多态。其中,抽象,封装,继承可以说多态的基础,而多态是封装,继承的具体表现。如果非要用专业术语来描述什么是多态的话

多态是指程序中定义的引用变量所指向具体类型和通过该引用变量发出的方法调用在编译的时候并不确定,而是程序运行期间才确定,就是说一个引用变量到底指向哪一个类的实例对象,该引用变量发出的方法调用哪一个类的中的方法,必须在程序运行期间才能确定。
记得大学时老师讲多态举的一个例子:上课铃响了,同学们都回各自教室上课,这就是多态。这就完了?如果是刚接触编程的同学来说,估计都懵逼了,我们那时就是这种状态。接下来我们用代码实现下老师说的意思。

多态实例
//上课铃响了
public class Ring
{

public void ringSound()
{
    System.out.println("我是铃声!!!");
}

}
1班的同学听到铃声回去上语文课

public class ClassRoom1 extends Ring
{

public void ringSound()
{
    System.out.println("classRoom1的同学听到铃声上语文了!!!");
}

}
2班的同学听到铃声回去上英语课

public class ClassRoom2 extends Ring
{

public void ringSound()
{
    System.out.println("classRoom2的同学听到铃声上英语了!!!");
}

}
Main类

public class Main
{

public static void main(String[] args)
{
    Ring ring = new ClassRoom1();
    Ring ring1 = new ClassRoom2();
    ring.ringSound();
    ring1.ringSound();
}

}
输出

classRoom1的同学听到铃声上语文了!!!
classRoom2的同学听到铃声上英语了!!!
这就是一个简单的的多态例子,我们从中不难发现,多态存在的几个关键点,

有继承关系(extends)
子类重写父类方法(ringSound)
父类引用指向子类对象 Ring ring = new ClassRoom1()
现在我们改下例子,看出现什么情况

public class Ring
{

public static void ringSound()
{
    System.out.println("我是铃声!!!");
}

}

这时发现ClassRoom1 和 ClassRoom2 都报错了,那我们也给他们都加上static

public class ClassRoom1 extends Ring
{

public static void ringSound()
{
    System.out.println("classRoom1的同学听到铃声上语文了!!!");
}

}
ClassRoom2类

public class ClassRoom2 extends Ring
{

public static void ringSound()
{
    System.out.println("classRoom2的同学听到铃声上英语了!!!");
}

}
预编译没报错了,那么输出应该是刚才的结果,main函数跑起来,输出

我是铃声!!!
我是铃声!!!
可以发现,结果并不是我们所想的那样。我们可以得出一个结论:在Java中static修饰的函数不能被子类重写。

其实Java中,父类含有一个静态函数,而且在他的子类也同样有一个返回类型,函数名,参数列表都相同的静态函数,子类实际上只是将父类中的该同名函数进行隐藏,而非重写,他们两个是完全没有关系的函数,所以他们的行为并不具有多态性。

注意:就是被final修饰的父类函数是无法被重写和private修饰的父类函数无法被继承。这是Java的规定,就不在举例说明

多态的作用
说了这么多,多态有什么作用

解耦,各种设计模式大多是基于多态实现的
复用性,子类处理父类即可
扩充和维护
多态缺点:不能使用子类的特有属性和行为。

多态分类
为了确定执行多态函数的哪一个,所以有两种情况:编译时多态,运行时多态

函数重载都是编译时多态,根据实际参数的数据类型,个数和顺序,Java在编译时就能够确定执行重载函数中的哪一个。

函数重写表现出两种多态性,当对象引用本类实例时,为编译时多态,否则为运行时多态。

public class Ring
{

public void ringSound()
{
    System.out.println("我是铃声!!!");
}

}
Main类

public class Main
{

public static void main(String[] args)
{

    ClassRoom2 ring1 = new ClassRoom2();//编译时多态,执行Ring类的ringSound
    ring1.ringSound(); //编译时多态,执行ClassRoom2 类的ringSound

    Ring ring = new ClassRoom2();
    ring.ringSound(); //运行时多态,是运行Ring的 ringSound 还是 ClassRoom2 类的ringSound 只有运行时在确定。

}

花木兰替父从军(https://www.zhihu.com/question/30082151/answer/120520568

花木兰替父亲花弧从军。那么这时候花木兰是子类,花弧是父类。花弧有自己的成员属性年龄,姓名,性别。花木兰也有这些属性,但是很明显二者的属性完全不一样。花弧有自己的非静态成员方法‘骑马杀敌’,同样花木兰也遗传了父亲一样的方法‘骑马杀敌’。花弧还有一个静态方法‘自我介绍’,每个人都可以问花弧姓甚名谁。同时花木兰还有一个自己特有的非静态成员方法‘涂脂抹粉’。但是,现在花木兰替父从军,女扮男装。这时候相当于父类的引用(花弧这个名字)指向了子类对象(花木兰这个人),那么在其他类(其他的人)中访问子类对象(花木兰这个人)的成员属性(姓名,年龄,性别)时,其实看到的都是花木兰她父亲的名字(花弧)、年龄(60岁)、性别(男)。当访问子类对象(花木兰这个人)的非静态成员方法(骑马打仗)时,其实都是看到花木兰自己运用十八般武艺在骑马打仗。当访问花木兰的静态方法时(自我介绍),花木兰自己都是用她父亲的名字信息在向别人作自我介绍。并且这时候花木兰不能使用自己特有的成员方法‘涂脂抹粉’。 -----------多态中的向上造型

那么终于一将功成万骨枯,打仗旗开得胜了,花木兰告别了战争生活。有一天,遇到了自己心爱的男人,这时候爱情的力量将父类对象的引用(花弧这个名字)强制转换为子类对象本来的引用(花木兰这个名字),那么花木兰又从新成为了她自己,这时候她完全是她自己了。名字是花木兰,年龄是28,性别是女,打仗依然那样生猛女汉子,自我介绍则堂堂正正地告诉别人我叫花木兰。OMG!终于,终于可以使用自己特有的成员方法‘涂脂抹粉’了。从此,花木兰完全回到了替父从军前的那个花木兰了。并且和自己心爱的男人幸福的过完了一生。 ------多态中的向下转型

花弧

public class HuaHu
{

int age = 60;

String name = "花弧";

String sex = "男";

public void horseKillEnemy()
{
    System.out.println("骑马杀敌");
}

public static void suggest()
{
    System.out.println("我叫花弧");
}

}
花木兰

public class HuaMuLan extends HuaHu
{

String name = "花木兰";

int age = 28;

String sex = "女";

public void horseKillEnemy()
{
    System.out.println("花木兰骑马杀敌");
}

public void  Prettify()
{
    System.out.println("花木兰涂脂抹粉");
}

}
替父从军

public class Main
{

public static void main(String[] args)
{
    //替父从军
    HuaHu huaHu = new HuaMuLan();
    System.out.println("姓名:" + huaHu.name + ",年龄:" + huaHu.age + ",性别:" + huaHu.sex); //其他人

    huaHu.horseKillEnemy();

    huaHu.suggest();  //用她父亲的名字信息在向别人作自我介绍

    //huaHu.Prettify() //无法使用

    //  战争结束了
    HuaMuLan huaMuLan = (HuaMuLan)huaHu;
    //花木兰变回自己
    System.out.println("姓名:" + huaMuLan.name + ",年龄:" + huaMuLan.age + ",性别:" + huaMuLan.sex);
    //自己特有函数
    huaMuLan.Prettify();

    System.out.println("幸福的过完了一生");
}

}
输出

姓名:花弧,年龄:60,性别:男
花木兰骑马杀敌
我叫花弧
姓名:花木兰,年龄:28,性别:女
花木兰涂脂抹粉
幸福的过完了一生
最后看个经典的多态例子

A类

public class A
{

public String show(D obj) {
    return ("A and D");
}

public String show(A obj) {
    return ("A and A");
}

}
B类

public class B extends A
{

public String show(B obj){
    return ("B and B");
}

public String show(A obj){
    return ("B and A");
}

}
C类

public class C extends B
{
}
D类

public class D extends B
{

}
Main类

public class Main
{

    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
你做对了吗?
原文地址https://www.cnblogs.com/dslx/p/10570559.html

相关文章
|
4月前
|
算法 Java 程序员
在Java的编程世界里,多态不仅仅是一种代码层面的技术,它是思想的碰撞,是程序员对现实世界复杂性的抽象映射,是对软件设计哲学的深刻领悟。
在Java的编程世界里,多态不仅仅是一种代码层面的技术,它是思想的碰撞,是程序员对现实世界复杂性的抽象映射,是对软件设计哲学的深刻领悟。
77 9
|
4月前
|
Java 开发者
在Java面向对象编程的广阔海洋中,多态犹如一股深邃的潜流,它推动着代码从单一走向多元,从僵化迈向灵活。
在Java面向对象编程的广阔海洋中,多态犹如一股深邃的潜流,它推动着代码从单一走向多元,从僵化迈向灵活。
44 7
|
4月前
|
Java 开发者
那些年,我们一同踏入Java编程的大门,多态,这个充满魔法的名字,曾无数次点亮我们探索面向对象编程的热情。
那些年,我们一同踏入Java编程的大门,多态,这个充满魔法的名字,曾无数次点亮我们探索面向对象编程的热情。
52 5
|
4月前
|
Java 程序员
让我们一起探讨Java多态的奥秘,看看它是如何打破“一刀切”的局限,让我们的代码更加生动多彩
让我们一起探讨Java多态的奥秘,看看它是如何打破“一刀切”的局限,让我们的代码更加生动多彩
45 5
|
4月前
|
Java 程序员
Java中的继承和多态:理解面向对象编程的核心概念
【8月更文挑战第22天】在Java的世界中,继承和多态不仅仅是编程技巧,它们是构建可维护、可扩展软件架构的基石。通过本文,我们将深入探讨这两个概念,并揭示它们如何共同作用于面向对象编程(OOP)的实践之中。你将了解继承如何简化代码重用,以及多态如何为程序提供灵活性和扩展性。让我们启程,探索Java语言中这些强大特性的秘密。
|
2月前
|
存储 Java 测试技术
Java零基础-多态详解
【10月更文挑战第10天】Java零基础教学篇,手把手实践教学!
35 4
|
2月前
|
Java 编译器 程序员
Java多态背后的秘密:动态绑定如何工作?
本文介绍了Java中多态的实现原理,通过动态绑定和虚拟方法表,使得父类引用可以调用子类的方法,增强了代码的灵活性和可维护性。文中通过具体示例详细解析了多态的工作机制。
75 4
|
3月前
|
Java 编译器
封装,继承,多态【Java面向对象知识回顾①】
本文回顾了Java面向对象编程的三大特性:封装、继承和多态。封装通过将数据和方法结合在类中并隐藏实现细节来保护对象状态,继承允许新类扩展现有类的功能,而多态则允许对象在不同情况下表现出不同的行为,这些特性共同提高了代码的复用性、扩展性和灵活性。
封装,继承,多态【Java面向对象知识回顾①】
|
2月前
|
Java
java继承和多态详解
java继承和多态详解
52 5
|
3月前
|
Java 编译器
Java——类与对象(继承和多态)
本文介绍了面向对象编程中的继承概念,包括如何避免重复代码、构造方法的调用规则、成员变量的访问以及权限修饰符的使用。文中详细解释了继承与组合的区别,并探讨了多态的概念,包括向上转型、向下转型和方法的重写。此外,还讨论了静态绑定和动态绑定的区别,以及多态带来的优势和弊端。
84 9
Java——类与对象(继承和多态)