首页 > 编程知识 正文

简述Java多态的概念,java如何实现多态

时间:2023-05-06 19:39:09 阅读:176931 作者:4661

说到多态性,离不开其他两大特性,即封装和继承。 多态性在它们的基础上出现,并密切相关。 在记忆中,每次学习面向对象,都与这三个特性有着密不可分的关系,多态性是面向对象的关键和难点。

是什么?文学角度:一千名读者拥有一千个雪白的蛋挞;

公司主管角度:上司承担同样的任务,每个人完成的情况不同

专业观点:同一类型的多个对象接收同一条消息时产生了不同的反应和效果;

从代码格式的角度看,3360父类的对象变量调用了子类中的重写方法。 请注意,通常具有一个父类,具有多个子类,并且在这些子类中同时重写父类的方法。)。

结论多态性的前提是有一个父级、多个子类。

做什么?

父类的对象变量可以引用此类的对象,也可以引用子类的对象。

因为Object类是超级根类(有个性的美女类),所以其对象变量可以参照所有类的对象。

特殊运算符:实例of属性

:子类的对象变量可以引用父类的对象吗?

答案不能是:

要执行此操作,必须强制转换。

也就是说,有两种类型的对象类型转换:

1 )通过发布:子类中的对象,可以将其直接分配给父类中的对象变量。  

这种现象也称为类型自动转换。

2 )向下转换:将强制父类引用转换为子类引用。  

:请注意,必须强制转换。

格式: (类型名称)对象变量;

如果父对象变量引用了子类中的对象,父类中的对象变量是否可以直接调用子类特定的方法?

答案是:否定的。

例如, Animal是父类,Dog是子类,getName ) )方法是Dog子类的特定方法。

因此,Anaimal a=new Dog (); 时、

a.getName (; 正确吗?

答:错误。

我怎么访问:

:需要先强制转换(向下转换)

类名对象变量=(子类名称)父类的对象变量;

即: Dog d=(Dog ) a;

随后,d.getName (; 这个时候,是正确的。

在什么情况下需要强制转换(撤消) (向下广播)对对象的引用?

1 )一定发生了多态性:

父级对象变量引用子类中的对象。

Object obj=new Student (;

2 )要访问(调用)子类对象的特定属性或方法。

父类的对象变量.子类的对象特定方法(属性); //错了。

Stringstr=obj.getSchool (; //错了。

()子类名称)父类的对象变量) .子类的对象特定方法(属性); //是的。

stringstr=(student ) obj ).getSchool ); //是的。

//多态性:父类的对象变量引用了子类的对象。

span style='font-size:18px;' span style='font-size:18px;' publicclassanimalstest { publicstaticvoidmain (string [ ] args ) {Animal a=new Animal ('动物'); Dog d1=new Dog ('狗','一张',true,2 ); Cat c1=new Cat ('猫'、'豆'、' blue ' ); system.out.println(a ); system.out.println(D1; system.out.println(C1; boolean flag=a instanceof Animal; 确定//a是否为Animal类型的system.out.println(flag ); flag=a instanceof Dog; system.out.println(flag ); flag=d1 instanceof Dog; system.out.println(flag ); flag=d1

instanceof Animal; //当结果为true时,说明它们之间存在继承关系。System.out.println( flag );//多态: 父类的对象变量引用了子类的对象。Animal a1 = new Dog("狗", "ABC", false, 3);//System.out.println( a1.getName() ); //调用a1的 getName()方法. 此时,它会去Animal类中找 getName()方法。若找不到,则报错。//判断a1是否拥有Dog类的特性,若有,则还原。if( a1 instanceof Dog ){Dog dd = (Dog)a1; //将a1强制转换为Dog类型。System.out.println( dd.getName() );}System.out.println("程序结束。");}}</span></span> 干什么?

 

在调用一个方法时,从源代码上看,无法确定调用了哪个对象的方法。只有在程序运行期间根据对象变量引用的实际对象才能确定此方法是

哪个对象的。这种现象称之为动态绑定 (联编)。

结论: 动态绑定的前提是:

1) 发生继承,且一个父类有多个子类。

2) 在每一个子类中对继承自父类的同一个方法实现了重写。

3) 发生多态,即: 父类对象变量引用了不同的子类对象。

4) 父类的对象变量调用了重写的方法,即: 发生了动态绑定。从而实现了多的价值。

为什么?

关于面向对象的三大特性,为了更好地理解我们为什么要用它,很有必要知道它带来的好处。当然,站在巨人的肩膀上学习总是高效的,分享一下:

封装性: 安全性和重用性。

继承性: 高效性和重用性。

多态性: 统一性(有机性)和高效性。

对于这三大特性的理解不同,可能会有不同的体会,例如:大自然不同的风景呈现,我们享受到的也不同,如果每天都面对着同一幅场景,后果是很可怕的。要想更好的理解,不断地实践是很不错的选择呢!

 

业务思想

 

学习的目的是为了更好地实践,要想在不断进行的项目中可以完成的更好、更为的轻松,这是离不开多态的。我们可以从最后一个demo中,看出加上动态绑定的图形选择,可以很有效的避免我们敲出很多图形的初始化代码,很高效,而且重复的初始化图形,很容易把我们惹毛的(当然这是开玩笑的),而我们要做的就是,尽量减少我们的工作负担,更为高效、轻松的完成。

多态,你一生都离不开的两个字,无论在哪里。

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

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

这一个小的程序 或许你体会不到多态的强度作用。其实说到多态就是 面向接口编程,它不和具体类尽心挂钩了
比如 你没用多态的话 ,
你没实例化一个对象 就要new一下,那假如你那天改变了需求了呢?那是不是又要改里面的?这样不好,所以 你可以通过多态,把需要相似的给提出来,然后继承它 这样 以后需要扩展你仅仅只是继承而已。这样就很简单。

这个需要多看代码 才可以更深刻理解。假设有一个类 叫 鸟类,它拥有属性翅膀,拥有方法鸣叫,如下
public class Bird{
private Wing wing;
public void moo(){
System.out.println("鸟叫声");
}
}
鸟类封装了 翅膀类和moo方法;另外有两个类都继承鸟类并重写了moo方法,分别是鹦鹉和麻雀如下:
鹦鹉类:
public class Parrot extends Bird{
public void moo(){
System.out.println("鹦鹉的叫声");
}
}
麻雀类:
public class Sparrow extends Bird{
public void moo(){
System.out.println("麻雀的叫声");
}
}
方法重写应该懂吧,不懂自己找书看吧;然后你有个妻子她想听鸟叫,就有个妻子类
public class Wife{
public void listen(Bird bird){
bird.moo();
}
/*这时多态就很好的体现了,你妻子想听鸟叫,无论什么鸟都可以给她,但是你想让她和鹦鹉
*说话,你就买了一只鹦鹉传给listen方法,结果你妻子听到了鹦鹉的叫声,程序输出:鹦
*鹉的叫声
*/
public static void main(String[] args) {
new Wife().listen(new Parrot());
}
}
多态实现了动态绑定,让程序有了很好的扩展性,比如你以后想买一只燕子送给你妻子,就只需要写个燕子类Swallow继承Bird方法就可以了,而不需要再在妻子类里添加一个方法listen(Swallow swallow)……上面编码没用编译器,可能有错误,请谅解

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。