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 只有运行时在确定。 }
花木兰替父亲花弧从军。那么这时候花木兰是子类,花弧是父类。花弧有自己的成员属性年龄,姓名,性别。花木兰也有这些属性,但是很明显二者的属性完全不一样。花弧有自己的非静态成员方法‘骑马杀敌’,同样花木兰也遗传了父亲一样的方法‘骑马杀敌’。花弧还有一个静态方法‘自我介绍’,每个人都可以问花弧姓甚名谁。同时花木兰还有一个自己特有的非静态成员方法‘涂脂抹粉’。但是,现在花木兰替父从军,女扮男装。这时候相当于父类的引用(花弧这个名字)指向了子类对象(花木兰这个人),那么在其他类(其他的人)中访问子类对象(花木兰这个人)的成员属性(姓名,年龄,性别)时,其实看到的都是花木兰她父亲的名字(花弧)、年龄(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
你做对了吗?
======================================================
如果有什么不对或错误,欢迎指正,lz好及时修改,不至于误导别人,万分感谢!!!
Java的多态浅谈的更多相关文章
- java之多态浅谈
多态是同一个行为具有多个不同表现形式或形态的能力. 父类中定义的属性和方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为 多态现实意义理解: 现实事物经常会体现出多种形态,如学生,学生是人的 ...
- java反射机制浅谈
一.Java的反射机制浅谈 最近研究java研究得很给力,主要以看博文为学习方式.以下是我对java的反射机制所产生的一些感悟,希望各位童鞋看到失误之处不吝指出.受到各位指教之处,如若让小生好好感动, ...
- Java基础之浅谈继承、多态
一.继承的理解 继承:简单通俗的来讲,继承就是一个类继承另一个类,通常用extends表示继承. 继承的类叫子类,被继承的类叫父类. 子类可以使用父类的变量和方法,同时也可以重写父类的方法. 在Jav ...
- Java系列1 -- 浅谈面向对象
也许每一个计算机专业的人,在大学学习java的时候,老师开始时都会说这么一句话,"Java是一门面向对象的语言".那么面向对象到底是什么,他有什么好处,或者他比其他流行的语言C/C ...
- java基础(十七)----- 浅谈Java中的深拷贝和浅拷贝 —— 面试必问
假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(boolean,char,byte,short, ...
- 【Java虚拟机】浅谈Java虚拟机
跨平台 Java的一大特性是跨平台,而Java是如何做到跨平台的呢? 主要依赖Java虚拟机,具体来说,是Java虚拟机在各平台上的实现. Java虚拟机在不同的平台有不同的实现.同一份字节码,通过运 ...
- Java基础之浅谈接口
前言 前几篇文章我们已经把Java的封装.继承.多态学习完了,现在我们开始比较便于我们实际操作的学习,虽然它也是Java基础部分,但是其实入门容易,精通很难. 我认真的给大家整理了一下这些必须学会.了 ...
- Java基础之浅谈集合
Java基础知识.关于List.Set.Map接口的了解,以及ArrayList.LinkedList.HashSet.TreeSet.HashMap.TreeMap...
- Java学习笔记——浅谈数据结构与Java集合框架(第二篇、Queue、Set)
江南好,何处异京华. 香散翠帘多在水,绿残红叶胜于花.无事避风沙. --<纳兰词> 诗词再好,大图不能忘 上大图: 先说说栈和队列: 栈就好比手枪的弹匣,你往里面压入子弹,最先压入的子弹就 ...
随机推荐
- kindeditor修改允许上传的图片、视频、音频大小
在jsp文件夹下,有个upload_json.jsp文件,打开找到: //最大文件大小 ; 修改数值即可.默认1000000,即为1M.
- Java基础知识总结【转+整合】
写代码: 1.明确需求.自己要做什么? 2.分析思路.怎么做? 3.确定步骤.每个思路部分用到哪些语句,方法和对象. 4.代码实现.用具体的java语言代码把思路体现出来. 学习新技术的四点: 1,该 ...
- 用js实现算法:冒泡排序、插入排序和快速排序
一.冒泡排序 function bubbleSort(arr){ for(var i=0;i<arr.length;i++){ for(var j=0;j<arr.length-i-1;j ...
- mysql学习 第二章 数据库的基本操作
3.1 创建数据库 MySQL安装好之后,首先需要创建数据库,这是使用MySQL各种功能的前提.本章将详细介绍数据的基本操作,主要内容包括:创建数据库.删除数据库.不同类型的数据存储引擎和存储引擎 ...
- Redis未授权访问
最近在做校招题目的时候发现有问到未授权访问,特此搭建了诸多未授权访问的环境并且一一复现并做简单总结.再次记录下来 环境介绍 0x00环境搭建 我这里用到的是Microsoft(R) Windows(R ...
- TensorFlow-谷歌深度学习库 图片处理模块
Module: tf.image 这篇文章主要介绍TensorFlow处理图片这一块,这个模块和之前说过的文件I/O处理一样也是主要从python导过来的. 通过官方文档,我们了解到这个模块主要有一下 ...
- PAT1084:Broken Keyboard
1084. Broken Keyboard (20) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue On a ...
- MySQL提示“too many connections”的解决办法
今天生产服务器上的MySQL出现了一个不算太陌生的错误"Too many connections".平常碰到这个问题,我基本上是修改/etc/my.cnf的max_connecti ...
- 【Java入门提高篇】Java集合类详解(一)
今天来看看Java里的一个大家伙,那就是集合. 集合嘛,就跟它的名字那样,是一群人多势众的家伙,如果你学过高数,没错,就跟里面说的集合是一个概念,就是一堆对象的集合体.集合就是用来存放和管理其他类对象 ...
- WPF MVVM UI分离之《交互与数据分离》
在我们使用WPF过程中,不可避免并且超级喜欢使用MVVM框架. 那么,使用MVVM的出发点是视觉与业务逻辑分离,即UI与数据分离 诸如下面的问题: 删除操作,假如需要先执行一部分数据的处理,然后删除界 ...