JavaSE基础知识学习-----多态

多态

Java面向对象编程有三大特性:封装,继承和多态
封装隐藏类的内部具体实现机制,保护数据,对外界隐藏内部细节,只向外部提供它所允许访问的方法
继承是为了复用代码和实现向上转型,当然继承也是为多态做准备。
多态可以说是Java面向对象的精华所在。

什么是多态

多态是指允许不同子类型的对象对同一消息做出不同的响应,简单来讲,就是用同样的对象调用同样的方法但是却做了不同的事情。也可以理解为一个事物的多种表现形态。
多态性分为编译时的多态性和运行时的多态性。例如:
方法重载:实现的是编译时的多态性
方法重写:实现的是运行是的多态性
子类对象的多态性,这个是Java多态性中最常用的事。

实现多态的条件

1.方法重写,也就是说要有继承吧,只有有了继承,子类重写了父类已有的或抽象的方法
2.对象造型,也就是说要有父类的引用指向子类对象
只有这样,同样的引用调用同样的方法就会作出不同的响应,简单来讲如下代码所示:
父类Person有如下方法:

public void walk(){
    System.out.println("人走路");
}

public void eat(){
    System.out.println("人吃饭");
}

如果子类Man类没有重写这两个方法,那么我们做如下的事情:

    Person man = new Man();
    man.walk();

输出结果:

人走路

综上所述:父类引用man指向的是子类对象,这个就是子类对象的多态性(也叫向上转型),man可以调用父类的方法,前提是子类没有重写父类方法。
如果子类Man类重写了父类方法

public void walk(){
    System.out.println("男人应该挺拔的走路");
}

public void eat(){
    System.out.println("男人应该多吃肉");
}

同样的调用:

Person man = new Man();
man.walk();

结果就是:

男人应该挺拔的走路

综上所述:子类对象重写了父类方法,那么man调用父类方法,执行的就是子类的方法。这个也虚拟方法调用,说到这里你应该可以猜到,什么是多态了吧,就是同样的父类对象应用,指向不同的子类对象,就会作出不同的响应,例如子类Woman类也重写了父类的方法:

public void walk(){
    System.out.println("女人应该温柔的走路");
}

public void eat(){
    System.out.println("女人应该少吃肉多吃水果蔬菜");
}

调用方法:

Person man = new Man();
Person woman = new Woman();
man.walk();
woman.walk();

结果为:

男人应该挺拔的走路
女人应该温柔的走路

综上所述:应该是很清晰了什么是子类对象的多态性,就是你相同的父类引用,不同的子类对象,就会响应对应的子类对象的方法。

方法重载和方法重写

方法重载和方法重写两者都是实现多态的方式,区别在于方法重载实现的是编译时的多态,方法重写实现的是运行时的多态,重载发生在同一个类中,同名的方法有不同的参数列表。

注意:方法的重载与返回值无关,简称两同一不同,同一个类,同一个方法,不同的参数列表

方法的重写发生在子类和父类之间,重写要求子类方法返回值,方法名,参数列表与父类爆出一致,权限修饰符大于父类,同时要同为static或同为非static。

注意:构造器不能被继承,所以不能被重写,但是却可以被重载

多态的使用例子

例如在父类Person类中有如下方法:

public void show(Person person){
    System.out.println("这是父类show方法");
}

子类Man类重写了子类方法:

public void show(Person person){
    System.out.println("这是子类show方法");
}

如果实例化Man对象,调用man的show(Person person)方法,就应该传入Person对象,这个时候就可以传入父类对象的引用。

Person man = new Man();
man.show(man);

父类引用指向不同的子类对象,作出不同的响应。

多态经典案例

摘自http://blog.csdn.net/thinkGhoster/archive/2008/04/19/2307001.aspx

    public class A {  
    public String show(D obj) {  
        return ("A and D");  
    }  
  
    public String show(A obj) {  
        return ("A and A");  
    }   
  
}  
  
public class B extends A{  
    public String show(B obj){  
        return ("B and B");  
    }  
      
    public String show(A obj){  
        return ("B and A");  
    }   
}  
  
public class C extends B{  
  
}  
  
public class D extends B{  
  
}  
  
public class Test {  
    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  

结果分析如下:

System.out.println("1--" + a1.show(b)); //a1是A的引用指向是A对象,故调用A中的show方法,传入的是b,b指向的是B对象,因为B继承与A,故传入的也可认为是A,结果为A and A
System.out.println("2--" + a1.show(c)); //c指向C对象,C继承B,B继承A,相当于传入A,结果为A and A
System.out.println("3--" + a1.show(d)); //d指向D对象,在A中有传入D对象的方法,结果为 A and D
System.out.println("4--" + a2.show(b)); //a2是父类引用,指向子类对象,按理说调用show方法会执行子类B的show方法,传入的是b,b指向的是B对象,
                                        //但是B中的show(B)是子类特有的方法,故不能被调用,传入的是B,B继承与A,相当于传入A,B类重写了show(B)方法,结果为B and A
System.out.println("5--" + a2.show(c)); //传入c,执行B中show(C)的方法,没有,C继承B,执行B中show(B),但是这是B中特有方法,不能被调用,
                                        //B继承A,调用B中show(A),结果B and A
System.out.println("6--" + a2.show(d)); //传入D,执行B中show(D)方法,没有,但是A中有就会执行父类show(D)方法,所以结果为:A and D
System.out.println("7--" + b.show(b)); //b指向B,传入B, 结果为B and B
System.out.println("8--" + b.show(c)); //传入c,执行B中show(C),没有,C继承B,执行B中show(B),结果为:B and B
System.out.println("9--" + b.show(d)); //传入d,执行B中show(D)方法,没有,当时B继承A,是存在A中show(D)的方法,结果为 A and D 

案例总结

对于a2.show(c)来讲,a2是A的应用,故先去A中找show(C)方法(this.show(O)),A中没有,按理应该去A的父类中找(super.show(O)),但是A没有父类,故只能在A中找show(c的父类)方法(this.show(super)),c的父类有B和A,A中找到show(A)的方法,但是B重写了该方法,故执行子类的方法,所以结果为B and A。找的顺序是this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,928评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,192评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,468评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,186评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,295评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,374评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,403评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,186评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,610评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,906评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,075评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,755评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,393评论 3 320
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,079评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,313评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,934评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,963评论 2 351

推荐阅读更多精彩内容

  • 一:java概述:1,JDK:Java Development Kit,java的开发和运行环境,java的开发工...
    ZaneInTheSun阅读 2,642评论 0 11
  • 、6一、基本知识 1.JDK和JRE的区别 答:JDK是java语言开发工具包,包含JRE和开发工具(javac....
    梦游的沙师弟阅读 1,202评论 0 4
  • 做个常客 文/笑看人生 做这里的常客 把书借阅 遨游知识海洋 精神就不会饥渴 做这里的常客 把所有书籍赏阅 用知识...
    笑看人生_b68a阅读 201评论 0 1
  • 文玩爱好者都很清楚,小叶紫檀瘤疤料是紫檀中非常稀有的料,为了搞清楚小叶紫檀手串瘤疤料到底有没有缺陷,首先得搞清楚小...
    文玩收藏集阅读 4,863评论 0 0
  • 【12月5日 338/3650 践行结果检视】 1,【晨间日记、每日要事、今日检视】——心得:全勤,今日吃青蛙*3...
    佩娜阅读 147评论 0 0