JAVA中,为什么要用多态,,怎么用请给个通俗易懂的例子解释下……

JAVA中,为什么要用多态,,怎么用请给个通俗易懂的例子解释下……,第1张

举个例子,显示鸟的飞行动作

对于八哥鸟,你可以这样new Myna()fly();

对于鹦鹉,你可以这样new Parrot()fly();

对于孔雀,你可以这样 new Peacock()fly();

。。。

对于每一个具体的鸟,你都必须调用具体的鸟类对象

现在使用多态再来看看。

我们先写一个Bird类,用来抽取出鸟类的飞行动作。

public abstract class Bird {

public void fly() {

Systemoutprintln("default bird fly!");

}

}

再写具体的鸟类,继承Bird类

class Parrot extends Bird {

@Override

public void fly() {

Systemoutprintln("Parrot fly");

}

}

class Myna extends Bird {

@Override

public void fly() {

Systemoutprintln("Myna fly");

}

}

现在再来看一下八哥和鹦鹉的飞行动作。

public static void main(String args[]) {

Bird bird = new Parrot();

birdfly();

bird = new Myna();

birdfly();

}

这样,同一个Bird的实例对象实际对调用的是八哥和鹦鹉的飞行动作。

假如这样还不清楚。那么现在有一个flyPerform()方法,显示具体的鸟的飞行行为。

flyPerform(Bird bird){

birdfly();

}

那么你就可以这样

flyPerform(new Parrot());

flyPerform(new Myna());

假如现在又有了一种新的鸟,NewBird那么我们只需要将new NewBird作为参数传入flyPerform方法即可,而不需要去修改这个方法的代码。

这是一个比较粗糙的例子,要不你仔细琢磨看看?

对于这个推荐答案,我不是很认同,

在java里面多态一般指的是运行时多态,重载多态是通过方法签名实现的,同一个方法名,但是要求参数必须不一样,这个在编译期间就可以确定调用的是哪个方法。

重载多态在C++上说的比较多些吧。

定义一个父类,比如父类有一个excute方法。写两个子类分别继承这个父类,分别实现这个excute方法。

class A{

abstract excute(){}

}

class B extend A

{

excute(){Systemoutprint( "I 'm B ");

}

class C extend A

{

excute()(){Systemoutprint( "I 'm C ");

}

用一个A的分别指向两个B、C的对象

A a1=new B();

A a2=new C();

分别调用excute方法 a1excute()、a2excute()是不是会打印出不同的句子呢? 明明都是A类型的引用调用了excute却会打印不同的句子,这就是多态。

父类引用指向子类对象是Java比较基础的概念。Java作为一门面向对象编程的语言,调用对象是在编程中经常用到的。北大青鸟为大家详细说明这一概念。

例如父类Animal,子类Cat,Dog。其中Animal可以是类也可以是接口,Cat和Dog是继承或实现Animal的子类。

Animalanimal=newCat();

即声明的是父类,实际指向的是子类的一个对象。

那这么使用的优点是什么,为什么要这么用?可以用这几个关键词来概括:多态、动态链接,向上转型。也有人说这是面向接口编程,可以降低程序

的耦合性,即调用者不必关心调用的是哪个对象,只需要针对接口编程就可以了,被调用者对于调用者是完全透明的。让你更关注父类能做什么,而

不去关心子类是具体怎么做的,你可以随时替换一个子类,也就是随时替换一个具体实现,而不用修改其他。

以后结合设计模式(如工厂模式,代理模式)和反射机制可能有更深理解。

下面介绍Java的多态性和其中的动态链接,向上转型:

面向对象的三个特征:封装、继承和多态;

封装隐藏了类的内部实现机制,可以在不影响使用者的前提下修改类的内部结构,同时保护了数据;

继承是为了重用父类代码,子类继承父类就拥有了父类的成员。

方法的重写、重载与动态连接构成多态性。Java之所以引入多态的概念,原因之一是它在类的继承问题上和C++不同,后者允许多继承,这确实给其

带来的非常强大的功能,但是复杂的继承关系也给C++开发者带来了更大的麻烦,为了规避风险,Java只允许单继承,派生类与基类间有IS-A的关系

(即“猫”isa“动物”)。这样做虽然保证了继承关系的简单明了,但是势必在功能上有很大的限制,所以,Java引入了多态性的概念以弥补这

点的不足,此外,抽象类和接口也是解决单继承规定限制的重要手段。同时,多态也是面向对象编程的精髓所在。

理解多态,首先要知道“向上转型”。

我定义了一个子类Cat,它继承了Animal类,那么后者就是前者是父类。我可以通过

Catc=newCat();

实例化一个Cat的对象,这个不难理解。但当我这样定义时:

Animala=newCat();

这代表什么意思呢?

很简单,它表示我定义了一个Animal类型的引用,指向新建的Cat类型的对象。由于Cat是继承自它的父类Animal,所以Animal类型的引用是可以指向

Cat类型的对象的。这就是“向上转型”。

1 public class Animal

2 {

3 public void bite()

4 {

5

6 }

7

8

9 public static void main(String args)

10 {

11 Animal A = new Cat();

12 Animal B = new Dog();

13

14 Abite();

15 Bbite();

16 }

17

18 }

19

20

21 class Cat extends Animal

22 {

23 public void bite()

24 {

25 Systemoutprintln("MiaoMiao is bitting");

26 }

27 }

28

29

30 class Dog extends Animal

31 {

32 public void bite()

33 {

34 Systemoutprintln("WangWang is bitting");

35 }

36 }

多态,顾名思义就是具有很多种形态,你可以联想到一种物质有很多种状态、形态,例如水,有气态、液态、固态,然后回归到编程,假如我们需要编程来实现对水的质量进行计算,在假设质量=密度体积。可是怎么样才能把所有形态、状态的水都能计算出来,这是就要分不同种情况了,假设是气态,这样就跟压强(假设的)有关系了,所以成员方法参数为压强、体积、密度。而液态的就有可能跟温度(假设的)关系比较大,所以成员方法中的参数为温度、体积、密度。而固态跟温度和压强(假设的啦)关系不大,那么成员方法的参数为体积、密度。这样计算水的质量就有3种计算公式了,虽然是不同的3条公式,但是他们殊途同归,最后都是求质量。

综上,多态就是为了解决同一问题的不同解决方式。使用前提就是一个对象(类)有多种情况,然后分情况进行解决。

运行时多态性是面向对象程序设计代码重用的一个最强大机制 动态性的概念也可以被说成 一个接口 多个方法 Java实现运行时多态性的基础是动态方法调度 它是一种在运行时而不是在编译期调用重载方法的机制 下面就继承和接口实现两方面谈谈java运行时多态性的实现

一 通过继承中超类对象引用变量引用子类对象来实现

举例说明

//定义超类superA

class superA

{

int i =

void fun()

{

System out println( This is superA )

}

}

//定义superA的子类subB

class subB extends superA

{

int m =

void fun()

{

System out println( This is subB )

}

}

//定义superA的子类subC

class subC extends superA

{

int n =

void fun()

{

System out println( This is subC )

}

}

class Test

{

public static void main(String[] args)

{

superA a

subB b = new subB()

subC c = new subC()

a=b

a fun()          ( )

a=c

a fun()          ( )

}

}

运行结果为

This is subB

This is subC

上述代码中subB和subC是超类superA的子类 我们在类Test中声明了 个引用变量a b c 通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用 也许有人会问 为什么( )和( )不输出 This is superA java 的这种机制遵循一个原则 当超类对象引用变量引用子类对象时 被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法 但是这个被调用的方法必须是在超类中定义过的 也就是说被子类覆盖的方法

所以 不要被上例中( )和( )所迷惑 虽然写成a fun() 但是由于( )中的a被b赋值 指向了子类subB的一个实例 因而( )所调用的fun()实际上是子类subB的成员方法fun() 它覆盖了超类superA的成员方法fun() 同样( )调用的是子类subC的成员方法fun()

另外 如果子类继承的超类是一个抽象类 虽然抽象类不能通过new *** 作符实例化 但是可以创建抽象类的对象引用指向子类对象 以实现运行时多态性 具体的实现方法同上例

不过 抽象类的子类必须覆盖实现超类中的所有的抽象方法 否则子类必须被abstract修饰符修饰 当然也就不能被实例化了

二 通过接口类型变量引用实现接口的类的对象来实现

接口的灵活性就在于 规定一个类必须做什么 而不管你如何做 我们可以定义一个接口类型的引用变量来引用实现接口的类的实例 当这个引用调用方法时 它会根据实际引用的类的实例来判断具体调用哪个方法 这和上述的超类对象引用访问子类对象的机制相似

举例说明

//定义接口InterA

interface InterA

{

void fun()

}

//实现接口InterA的类B

class B implements InterA

{

public void fun()

{

System out println( This is B )

}

}

//实现接口InterA的类C

class C implements InterA

{

public void fun()

{

System out println( This is C )

}

}

class Test

{

public static void main(String[] args)

{

InterA a

a= new B()

a fun()

a = new C()

a fun()

}

}

输出结果为

This is B

This is C

上例中类B和类C是实现接口InterA的两个类 分别实现了接口的方法fun() 通过将类B和类C的实例赋给接口引用a而实现了方法在运行时的动态绑定 充分利用了 一个接口 多个方法 展示了Java的动态多态性

需要注意的一点是 Java在利用接口变量调用其实现类的对象的方法时 该方法必须已经在接口中被声明 而且在接口的实现类中该实现方法的类型和参数必须与接口中所定义的精确匹配

lishixinzhi/Article/program/Java/hx/201311/26085

1--:a1是类A的实例,所以只能调用A类中的show方法,参数b是类B的实例,B又是A的子类,所以只能调用类A中参数是A obj的那个方法,因为b只能转换为父类型A,不能转换为子类型D

2--:道理同上。

3--:道理同上。

由于前三条的变量类型和对象类型相同,不涉及多态,仅仅是重载的问题。

4--:此条代码是难点,这里涉及到了重写和重载的概念,把重写和重载彻底理解了,你就知道为什么输出是B and A了。重写是子类中的方法和父类中的方法同名,同返回类型,同类型参数。

而重载是同一个类中的两个方法(注意是同一个类中),名相同,但是参数类型不同或者数量不同。因为a2引用的是B类的实例,所以要去B类中找重写的show方法,而不是重载的。所以只能调用参数类型是A的那个方法。

5--:道理同第4条。

6--:B类中继承了A类的参数为D类型的show方法,只继承而没有重写。也就是B类中实际有三个方法,所以此条代码调用的是参数为D的方法。

7--:把上面的都理解了。7,8,9条代码就很容易理解了。

7,8,9和1,2,3一样不存在多态,仅仅是重载方法的调用。多态是父类变量引用子类对象才会发生的。变量类型和对象类型相同,只会涉及重载,和重写无关。

你发的这段代码,我在网上找到了一个博文,看了他的解释,开始我觉得很难理解,后来才明白,他的解释是混乱的。正确的原理是重写和重载。只要你把重写和重载的区别理解透彻,这段代码就容易理解了。

以上就是关于JAVA中,为什么要用多态,,怎么用请给个通俗易懂的例子解释下……全部的内容,包括:JAVA中,为什么要用多态,,怎么用请给个通俗易懂的例子解释下……、在Java中有哪些是多态性的表现,举例说明。、java多态的总结等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/9687496.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-30
下一篇2023-04-30

发表评论

登录后才能评论

评论列表(0条)

    保存