导航:首页 > 源码编译 > 编译期多态和运行期多态的优缺点

编译期多态和运行期多态的优缺点

发布时间:2022-09-21 04:30:57

1. java多态问题

应该是你没有完全理解,编译时多态其实是较浅层次的,并不是多态的精髓所在,运行时多态才是精髓所在。
编译时多态其实完全可以用不同的方法名来解决,编程者在写代码的时候,就完全知道该调用哪一个方法,这其实并不是多态,而是一种语法现象,让你可以把相似功能但参数不同的方法,可以写成同样的名字,写的时候不必为相似功能的一系列函数起名而绞尽脑汁,阅读时一看几个方法名字都一样,哦,重载了。
真正意义上的多态,是使用虚拟调用的技术来实现,确保你对象名.方法名,可以在运行时调用到正确的方法。
真正意义的多态,在编码时,并不能确定调用的是哪一个继承级别的方法实现,这个留在运行时解决,带来的好处是代码有更好的抽象度。
顺便提一下,以不同参数,同样方法名的重载,和Override(重写/覆盖),是两个事情,不要弄混。

2. 什么是多态性,使用多态有什么好处

什么是多态?

可以这么回答:

使用多态有什么好处?

多态在代码中的体现:

输出结果:
猫吃鱼
猫吃鱼(因为描述的是真正的是一只猫)

拓展:

多态性:同一操作作用于不同的对象,可以用不同的解释,产生不同的执行结果,这就是多态性。

多态性通过派生类覆写基类中的虚函数的方法来实现。

多态性分为两种,一种是编译时的多态性,一种是运行时的多态性。

编译时的多态性:编译时多态是通过重载来实现的。对于非虚的成员来说,系统在编译时,根据传递的参数,返回的类型等信息决定实现何种操作。

运行时的多态性:运行时的多态性就是指直到系统运行时,才根据实际情况决定实现何种操作。

3. 面向对象的多态详解 !!

面向对象的软件开发语言具有三个重要的特点分别为封装性、继承性、多态性。封装性即意味着对象封装其内部的数据,使其对外不可见,以保证数据的安全性。继承性是代码复用的一个很好的解决方案,但是继承关系是编译器在编译阶段就为所有的对象决定的,因而在软件工程过程中,继承性太过死板,存在很大的局限性。而多态性,它是将多种不同的特殊行为进行抽象的一种能力,通过结合继承性,多态性很好地解决了OO遇到的很多麻烦,使得面向对象的编程方式最终得到淋漓尽致的推广。

多态性和泛型编程

各种编程语言都内置了多种基本数据结构并且支持自定义数据类型,因而程序员在程序设计过程中可能会遇到多种数据类型,而针对这些数据类型的逻辑操作很有可能是雷同的。此时为每一种数据类型都设计出相应的逻辑函数似乎已经变得很不现实,因而泛型编程孕育而生了。泛型编程的出现,可以说在软件工程领域里是一个极大的进步。利用泛型编程,我们可以不为特定的类型进行专门编码,而采用对不同类型进行通用编码的方式来解决应对大量数据类型的问题。C++
STL是泛型编程的成功案例。利用Template函数,STL成功实现了对多种数据类型进行泛化的效果。而OO通过接口或者抽象类进一步实现了对类的泛化,也就是在面向对象过程中出现的新名词—多态!

多态性特点

简单来说,多态是具有表现多种形态的能力的特征,在OO中是指,语言具有根据对象的类型以不同方式处理,即指同样的消息被不同类型的对象接收时导致完全不同的行为,是对类的特定成员函数的再抽象。多态性在不同的编程语言中拥有不同的解决方案,但多态性的最终目标却始终不变,都是“以不变应万变”。

两种多态方式

一般来说,多态主要是存在两种类型:编译时的多态和运行时的多态。

1
编译时的多态主要是通过函数重载来实现的。所谓函数重载是指保持函数名不变,主要通过更改函数形参的个数以及形参的类型来定义出多个同名函数来实现对多种类型数据的逻辑处理。这种类型的多态关系是编译器在编译阶段就已经在函数调用的地方确定的,因而运行过程中速度较快,但功能比较局限。

2
运行时的多态在不同的语言中拥有不同的实现方案。C++通过虚函数的晚捆绑来实现,而Java通过面向接口编程和面向抽象编程来实现动态调用相应的函数实现。但归根结点,这些语言都是通过将多种特殊实现的类抽象为一个泛化类来实现运行多态。

面向接口编程

软件工程中程序涉及到的对象越多,对象之间相似的概率越大,因而这时候抽象变成了可能。通过定义接口,程序设计者可以成功实现对方法的定义和实现的分离,因而应用程序不必考虑子类成员函数中是如何实现内部逻辑细节,只需知道该类对象向外公开的接口便可成功操纵这类对象。而这种编程方式,为以后程序的改动以及程序的健壮性和扩展性都提供了一个比较理想的解决方案。因此面向抽象编程已经成为OO界强烈推崇的编程方式。

OO思想已经深入广大编程人员的工作中,如何能够充分合理利用OO的特点达到最优化软件体系结构将会成为每一个OO程序员应该思考的问题,相信OO思想能够为大家的软件设计带来前所未有的效果。

4. java中多态性什么意思

多态性:顾名思义就是拥有“多种形态”的含义,是指属性或方法在子类中表现为多种形态。

在JAVA中有两种多态是指:运行时多态和编译时多态。多态性是面向对象的核心特征之一,类的多态性提供类中成员设计的灵活性和方法执行的多样性。

多态指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)

实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。

展资料:

多态的好处:

1、可替换性(substitutability)多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。

2、可扩充性(extensibility)多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。

3、接口性(interface-ability)多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。

4、灵活性(flexibility)它在应用中体现了灵活多样的操作,提高了使用效率。

5、简化性(simplicity)多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。

5. 编译时的多态性和运行时的多态性在实现方法上有何不同

我不知道你哪本书上看到的,但是,只要不是后绑定就不能称为多态,前绑定只能称为代码重用,比如函数的重载、覆盖以及一般的类继承。
多态的关键特点就是:在运行时虚基类指针指向派生类对象地址,而将派生类对象地址赋值给基类指针,这就是所谓的后绑定,编译时绑定称为前绑定,因此多态另一个特点就是“动态“。换句话说,如果是后绑定,编译器事先是不知道在运行时指针将指向哪一种派生类的对象,因此基类指针必须是“虚“的,虚基类中不能有任何实现只有定义,此时虚基类的作用就是一个类接口,这样才能在编译时“模糊”掉类型匹配原则,基类的作用只是个约定,定义了函数调用格式,而只在运行时才确定指针具体指向哪一个对象。
而所谓编译时的多态性根本不存在,如果编译器能确定基类指针指向哪一个派生类对象地址,就不是多态,哪怕你采用重载覆盖或者继承,这些编译器已经可以预知的事情,一旦编译完成就固定了,运行时无法更改的,比如你不能在不重新编译的情况下增加一个重载,这就制约了程序运行时的灵活性以及可扩充性。而多态完全可以实现“热“更新,更多的是便于程序的可扩充性。你完全可以将派生类编译在DLL中,每当更新程序时,只要替换掉DLL而不用重新编译全部代码。

6. JAVA中使用多态有的好处。有什么用处

多态有编译时多态 和运行时多态。
第一个是通过方法重载实现;第二个是通过方法覆盖实现(子类覆盖父类方法)。
第一种就是我们调用方法是不用区分参数类型,程序会自动执行相应方法,如: 加法运算,可以使int相加,可以是double相加,都是同一个方法名。
第二种就是动态绑定,使用父类引用指向子类对象,再调用某一父类中的方法时,不同子类会表现出不同结果。 这样的作用就是扩展性极好,玩过网游的话应该知道 游戏中有不同的角色,它们都有一个父类,它们做相同动作时表现出来的效果就会不一样,比如跑,魔法师的跑跟战士的跑就不会一样,这就是俩者都覆盖了父类中的跑方法,各自有自己的现实,表现出来多态。 如果有一天你想再加个角色,只用再写一个类继承该父类,覆盖其中的跑方法就行了,其他代码不用怎么改,所以可维护性也很好。

7. 谈谈你对Java中的多态的理解.(为什么要使用多态,有什么好处,一般用在什么场合)

面向对象编程有三大特性:封装、继承、多态。

封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据。对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法。

继承是为了重用父类代码。两个类若存在IS-A的关系就可以使用继承。,同时继承也为实现多态做了铺垫。

那么什么是多态呢?多态的实现机制又是什么?请看我一一为你揭开:

所谓多态

就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。



比如你是一个酒神,对酒情有独钟。某日回家发现桌上有几个杯子里面都装了白酒,从外面看我们是不可能知道这是些什么酒,只有喝了之后才能够猜出来是何种酒。你一喝,这是剑南春、再喝这是五粮液、再喝这是酒鬼酒….在这里我们可以描述成如下:

酒 a = 剑南春

酒 b = 五粮液

酒 c = 酒鬼酒

这里所表现的的就是多态。剑南春、五粮液、酒鬼酒都是酒的子类,我们只是通过酒这一个父类就能够引用不同的子类,这就是多态——我们只有在运行的时候才会知道引用变量所指向的具体实例对象。

诚然,要理解多态我们就必须要明白什么是“向上转型”。在继承中我们简单介绍了向上转型,这里就在啰嗦下:在上面的喝酒例子中,酒(Win)是父类,剑南春(JNC)、五粮液(WLY)、酒鬼酒(JGJ)是子类。我们定义如下代码:

JNC a = new JNC();

对于这个代码我们非常容易理解无非就是实例化了一个剑南春的对象嘛!但是这样呢?

Wine a = new JNC();


在这里我们这样理解,这里定义了一个Wine 类型的a,它指向JNC对象实例。由于JNC是继承与Wine,所以JNC可以自动向上转型为Wine,所以a是可以指向JNC实例对象的。这样做存在一个非常大的好处,在继承中我们知道子类是父类的扩展,它可以提供比父类更加强大的功能,如果我们定义了一个指向子类的父类引用类型,那么它除了能够引用父类的共性外,还可以使用子类强大的功能。


但是向上转型存在一些缺憾,那就是它必定会导致一些方法和属性的丢失,而导致我们不能够获取它们。所以父类类型的引用可以调用父类中定义的所有属性和方法,对于只存在与子类中的方法和属性它就望尘莫及了。



publicclassWine{
publicvoidfun1(){
System.out.println("Wine的Fun.....");
fun2();
}

publicvoidfun2(){
System.out.println("Wine的Fun2...");
}
}

publicclassJNCextendsWine{
/**
*@desc子类重载父类方法
*父类中不存在该方法,向上转型后,父类是不能引用该方法的
*@parama
*@returnvoid
*/
publicvoidfun1(Stringa){
System.out.println("JNC的Fun1...");
fun2();
}

/**
*子类重写父类方法
*指向子类的父类引用调用fun2时,必定是调用该方法
*/
publicvoidfun2(){
System.out.println("JNC的Fun2...");
}
}

publicclassTest{
publicstaticvoidmain(String[]args){
Winea=newJNC();
a.fun1();
}
}

-------------------------------------------------

Output:

Wine的Fun.....

JNC的Fun2...


从程序的运行结果中我们发现,a.fun1()首先是运行父类Wine中的fun1().然后再运行子类JNC中的fun2()。

分析:在这个程序中子类JNC重载了父类Wine的方法fun1(),重写fun2(),而且重载后的fun1(String a)与 fun1()不是同一个方法,由于父类中没有该方法,向上转型后会丢失该方法,所以执行JNC的Wine类型引用是不能引用fun1(String a)方法。而子类JNC重写了fun2() ,那么指向JNC的Wine引用会调用JNC中fun2()方法。

所以对于多态我们可以总结如下:

指向子类的父类引用由于向上转型了,它只能访问父类中拥有的方法和属性,而对于子类中存在而父类中不存在的方法,该引用是不能使用的,尽管是重载该方法。若子类重写了父类中的某些方法,在调用该些方法的时候,必定是使用子类中定义的这些方法(动态连接、动态调用)。

对于面向对象而已,多态分为编译时多态和运行时多态。其中编辑时多态是静态的,主要是指方法的重载,它是根据参数列表的不同来区分不同的函数,通过编辑之后会变成两个不同的函数,在运行时谈不上多态。而运行时多态是动态的,它是通过动态绑定来实现的,也就是我们所说的多态性。




多态的实现

2.1实现条件

在刚刚开始就提到了继承在为多态的实现做了准备。子类Child继承父类Father,我们可以编写一个指向子类的父类类型引用,该引用既可以处理父类Father对象,也可以处理子类Child对象,当相同的消息发送给子类或者父类对象时,该对象就会根据自己所属的引用而执行不同的行为,这就是多态。即多态性就是相同的消息使得不同的类做出不同的响应。

Java实现多态有三个必要条件:继承、重写、向上转型。

继承:在多态中必须存在有继承关系的子类和父类。

重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。

向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。

只有满足了上述三个条件,我们才能够在同一个继承结构中使用统一的逻辑实现代码处理不同的对象,从而达到执行不同的行为。

对于Java而言,它多态的实现机制遵循一个原则:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。


2.2实现形式

在Java中有两种形式可以实现多态。继承和接口。

2.2.1、基于继承实现的多态

基于继承的实现机制主要表现在父类和继承该父类的一个或多个子类对某些方法的重写,多个子类对同一方法的重写可以表现出不同的行为。

publicclassWine{
privateStringname;

publicStringgetName(){
returnname;
}

publicvoidsetName(Stringname){
this.name=name;
}

publicWine(){
}

publicStringdrink(){
return"喝的是"+getName();
}

/**
*重写toString()
*/
publicStringtoString(){
returnnull;
}
}

publicclassJNCextendsWine{
publicJNC(){
setName("JNC");
}

/**
*重写父类方法,实现多态
*/
publicStringdrink(){
return"喝的是"+getName();
}

/**
*重写toString()
*/
publicStringtoString(){
return"Wine:"+getName();
}
}

publicclassJGJextendsWine{
publicJGJ(){
setName("JGJ");
}

/**
*重写父类方法,实现多态
*/
publicStringdrink(){
return"喝的是"+getName();
}

/**
*重写toString()
*/
publicStringtoString(){
return"Wine:"+getName();
}
}

publicclassTest{
publicstaticvoidmain(String[]args){
//定义父类数组
Wine[]wines=newWine[2];
//定义两个子类
JNCjnc=newJNC();
JGJjgj=newJGJ();

//父类引用子类对象
wines[0]=jnc;
wines[1]=jgj;

for(inti=0;i<2;i++){
System.out.println(wines[i].toString()+"--"+wines[i].drink());
}
System.out.println("-------------------------------");

}
}

OUTPUT:

Wine:JNC--喝的是JNC

Wine:JGJ--喝的是JGJ



在上面的代码中JNC、JGJ继承Wine,并且重写了drink()、toString()方法,程序运行结果是调用子类中方法,输出JNC、JGJ的名称,这就是多态的表现。不同的对象可以执行相同的行为,但是他们都需要通过自己的实现方式来执行,这就要得益于向上转型了。

我们都知道所有的类都继承自超类Object,toString()方法也是Object中方法,当我们这样写时:



Objecto=newJGJ();

System.out.println(o.toString());


输出的结果是Wine : JGJ。

Object、Wine、JGJ三者继承链关系是:JGJ—>Wine—>Object。所以我们可以这样说:当子类重写父类的方法被调用时,只有对象继承链中的最末端的方法才会被调用。但是注意如果这样写:


Objecto=newWine();

System.out.println(o.toString());

输出的结果应该是Null,因为JGJ并不存在于该对象继承链中。

所以基于继承实现的多态可以总结如下:对于引用子类的父类类型,在处理该引用时,它适用于继承该父类的所有子类,子类对象的不同,对方法的实现也就不同,执行相同动作产生的行为也就不同。

如果父类是抽象类,那么子类必须要实现父类中所有的抽象方法,这样该父类所有的子类一定存在统一的对外接口,但其内部的具体实现可以各异。这样我们就可以使用顶层类提供的统一接口来处理该层次的方法。




2.2.2、基于接口实现的多态

继承是通过重写父类的同一方法的几个不同子类来体现的,那么就可就是通过实现接口并覆盖接口中同一方法的几不同的类体现的。

在接口的多态中,指向接口的引用必须是指定这实现了该接口的一个类的实例程序,在运行时,根据对象引用的实际类型来执行对应的方法。

继承都是单继承,只能为一组相关的类提供一致的服务接口。但是接口可以是多继承多实现,它能够利用一组相关或者不相关的接口进行组合与扩充,能够对外提供一致的服务接口。所以它相对于继承来说有更好的灵活性。

8. 请问一下Java里编译时多态和运行时多态的区别,最好举个例,谢谢

个人看法
多态的概念 父类引用指向子类对象 而实际调用的方法为子类的方法。
编译时多态 Java里叫重载 严格来说不叫多态 运行时多态 有继承 有重写 父类引用指向子类对象
例子我看就算了 书上多 的是

9. 关于Java的编译时多态和运行时多态

您想的有点复杂化了,简单的说吧,您说的运行时的多态是分为可执行文件和非可执行文件,也就是说您的程序打没打包,而您说的编译时的多态也分为两种;1、重载。2、继承。前者是静态的多态形式也就是说不可以用于多个类;针对方法,后者是可以在多个类之间使用,要记得只可以子类继承父类,不可‘以下犯上’。就像是java中的类型,一个是private,另一个是public。

阅读全文

与编译期多态和运行期多态的优缺点相关的资料

热点内容
美团的服务器是什么 浏览:357
axure原型设计精髓pdf 浏览:376
svox文件夹有用吗 浏览:506
怎样才可以给软件添加密钥 浏览:587
光纤通信原理pdf 浏览:207
c需要用什么编译器 浏览:702
python设置断点调试 浏览:313
pc手柄怎么连接安卓 浏览:33
dll解压不成功 浏览:343
连接地址服务器失败是什么 浏览:399
台达dvp14ss2编程电缆 浏览:133
单片机开发板设置技巧 浏览:343
阿里云服务器怎么配置git 浏览:414
androidcameraid 浏览:430
活塞式空气压缩机原理 浏览:791
vt编辑编制编译 浏览:807
抖音优质创作者推荐程序员 浏览:75
摄像机多控神器让拍摄轻松解压 浏览:422
杭州的服务器地址 浏览:277
全医药学大词典pdf 浏览:809