----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
如果说继承,抽象类,接口可以让我们组建一个能够实现复杂功能多层次的继承体系,那么多态就是对这个体系的应用。多态实现了对事物定义和实现的分离,就是说将做什么和怎么做分开。多态降低了类与类直接的耦合性,从而提高了扩展性。
继承体系中的对象,既可以被做为它本身的类型,也可以被当做它的基类。这也是是实现多态的前提。
多态
多态也是面向对象的特征之一。
多态:可以理解为事物存在的多种体现形态
人:男人,女人
动物:猫,狗。
猫 x = new 猫();
动物 x = new 猫();
多态的体现
父类的引用指向了自己的子类对象。
父类的引用也可以接收自己的子类对象。
多态的前提
必须是类与类之间有关系。要么继承,要么实现。
通常还有一个前提:存在覆盖。
多态的好处
预先定义的程序可以运行后期程序的内容。
多态的出现大大的提高程序的扩展性。
多态的弊端
虽然可以预先使用,但是只能访问父类中已有的功能,运行的是后期子类的功能内容。
不能预先使用子类中定义的特有功能。
多态的应用
package itcast.heima; //为了提高主板功能的扩展性。 //定义了规则。让后期的出现的功能板块, //只要覆盖该规则,就可以被这个主板使用。 interface PCI { public void open(); public void close(); } class MainBoard{ public void run(){ System.out.println("mainboard run"); } public void usePCI(PCI p){ //判断p是否指向实体对象 if(p!=null){ p.open(); p.close(); } } } class NetCard implements PCI{ public void open(){ System.out.println("NetCard open"); } public void close(){ System.out.println("NetCard close"); } } class SoundCard implements PCI{ public void open(){ System.out.println("SoundCard open"); } public void close(){ System.out.println("SoundCard close"); } } public class DuoTaiDemo5 { public static void main(String[] args) { MainBoard mb = new MainBoard(); mb.run(); mb.usePCI(null); mb.usePCI(new NetCard()); mb.usePCI(new SoundCard()); } }
NetCard和SoundCard都实现了PCI接口,所以可以被当做PCI对象传入usrPCI(PCI p)方法中,即使在后期
我们
在多态中成员函数的特点
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法。
简单总结就是:成员 函数在多态调用时,编译看左边,运行看右边。
对待静态方法编译和运行都看左边,因为静态方法先于对象已经存在。
package itcast.heima;
class Fu
{
int num = 5;
void method1()
{
System.out.println("fu method_1");
}
void method2()
{
System.out.println("fu method_2");
}
static void method4()
{
System.out.println("fu method_4");
}
}
class Zi extends Fu
{
int num = 8;
void method1()
{
System.out.println("zi method_1");
}
void method3()
{
System.out.println("zi method_3");
}
static void method4()
{
System.out.println("zi method_4");
}
}
class DuoTaiDemo4
{
public static void main(String[] args)
{
Fu f = new Zi();
System.out.println(f.num);
f.method4();
Zi z = new Zi();
z.method4();
}
}
打印结果
f.method4()和z.method4()都是调用的的子类的方法。
如果父类中没有此方法,子类中有此方法,将编译失败。
反之将运行失败。
在多态中,成员变量的特点
无论编译和运行,都参考左边(引用型变量所属的类)。
例子来源于thinking in java
package itcast.heima;
class Super {
public int field = 0;
public int getField(){
return field;
}
}
class Sub extends Super {
public int field = 1;
public int getField(){
return field;
}
public int getSuperField(){
return super.field;
}
}
public class FieldAccess {
public static void main(String[] args) {
Super sup = new Sub();
System.out.println("sup.field:" + sup.field +
" sup.getField():" + sup.getField());
Sub sub = new Sub();
System.out.println("sub.field:" + sub.field +
" sub.getField():" + sub.getField() +
" sub.getSuperField():" + sub.getSuperField());
}
}
打印结果
可以看出成员变量是跟着引用走的,哪个对象去访问field,就返回哪个对象的field。thing in
java中认为,任何域的访问操作都是有编译器解析的,因此不是多态。在本例中field有两个Super.field和Sub.field。Super只包含Super.field。而Sub两个都包含,但默认默认域Sub.field。
因此才会有以上结果。当去掉Sub.field域后,Sub的中就只有Super.field。这是sub.field和field.getField()都将访问父类的field=0;
涉及到构造函数的多态
package itcast.heima;
abstract class Glyph {
abstract void draw();
Glyph() {
System.out.println("Glyph() before draw()");
draw();
System.out.println("Glyph() after draw()");
}
}
class RoundGlyph extends Glyph {
int radius = 1;
RoundGlyph(int r) {
radius = r;
System.out.println(
"RoundGlyph.RoundGlyph(), radius = "
+ radius);
}
void draw() {
System.out.println(
"RoundGlyph.draw(), radius = " + radius);
}
}
public class PolyConstructors {
public static void main(String[] args) {
new RoundGlyph(5);
}
}
这里首先涉及到了继承中的对象初始化,创建一个子类是,会先去调用父类的构造函数,而后运行自己的构造器。但是在调用父类构造函数之前,子类对象会首先给对象赋予默认初始化值。所以radius在被父类构造函数运行之前会被赋值0,父类构造函数运行完后,会给radius显
示初始化radius=5,最后执行子类构造函数。
在这段代码中运行父类构造函数时,它调用了draw()方法,而draw()方法又被子类覆盖,所以父类构造函数运行的是RoundGlyph.draw(),正是这个方法可以访问子类中尚未初始化的数据(显示初
始化和构函数初始化)这会带来意想不到的麻烦,且相当隐蔽,所以尽量不要在父类构造器中访问被子类覆盖的方法。
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
相关推荐
Java__多态案例.mp4
Java__多态上.mp4
Java__多态下.mp4
java的多态例子,适合初学者学习java的多态特性
抽象类_接口_多态_继承整合案例.。
NULL 博文链接:https://zsl131.iteye.com/blog/626615
多态系统的贝叶斯网络模型的参数学习算法,基于Noisy-Max模型
接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象...Java中多态的代码体现在一个子类对象(实现类对象)既可以给这个子类(实现类对象)引用变量赋值,又可以给这个子类(实现类对象)的父类(接口)变量赋值。
上机01_多态实现器乐演奏.zip
Labview多态VI计算输入数组字节和,自适应输入数组数据类型。
本代码中有:“包含与继承”、“虚函数与多态”、“模板”程序例子
黑马程序员匠心之作 C++教程讲义,适合初学者,视频教程全程无废话
动力节点的Java课程适合绝对零基础的观看,教程中讲解了Java开发环境搭建、Java的基础语法、Java的面向对象。每一个知识点都讲解的非常细腻,由浅入深。适合非计算机专业,想转行做Java开发的朋友,或者想让Java基础...
动力节点的Java课程适合绝对零基础的观看,教程中讲解了Java开发环境搭建、Java的基础语法、Java的面向对象。每一个知识点都讲解的非常细腻,由浅入深。适合非计算机专业,想转行做Java开发的朋友,或者想让Java基础...
动力节点的Java课程适合绝对零基础的观看,教程中讲解了Java开发环境搭建、Java的基础语法、Java的面向对象。每一个知识点都讲解的非常细腻,由浅入深。适合非计算机专业,想转行做Java开发的朋友,或者想让Java基础...
企业中包括普通员工、中层管理人员、财务人员、高层管理人员等。每类人员可能具有不同的基本信息,或拥有不同的功能操作。1) 每个员工都具有基本信息(姓名、性别、年龄、职务、工作时间等)但是根据员工类型不同...
C++类,继承,多态方面的PPT资料,非常全
java多态、继承练习题,包含题目与答案,............................................................................................................
黑马程序员 - Java基础教学 - 08 - 面向对象(4)-多态.doc
代码演示//父类//子类class cat extends Animal{//多态演示public static void main(String[] args