🎉一.多态
1.1多态的概念
多态是同一个行为具有多个不同表现形式或形态的能力。
多态就是同一个接口,使用不同的实例而执行不同操作,举个例子,生活中的榨汁机,我们都是把水果放到榨汁机中去榨汁,但是你放进去什么水果,它就榨出来相对于的果汁,榨汁是一种行为,榨出来不同的的果汁就是不同的表现形式,希望这个例子可以帮助大家理解!
1.2多态的实现条件
👜在J ava 中要实现多态,必须要满足如下几个条件,缺一不可:
1. 必须在继承体系下
2. 子类必须要对父类中方法进行重写
3. 通过父类的引用调用重写的方法
1.3向上转型和向下转型
1)向上转型
向上转型:实际就是创建一个子类对象,将其当成父类对象来使用。
语法格式:父类类型 对象名 = new 子类类型 ()
我们来举个例子:
classAnimal { publicStringname; publicintage; publicvoidsleep() { System.out.println(name+"正在睡觉!"); } } classDogextendsAnimal { publicvoidwangwang() { System.out.println(name+"汪汪叫!"); } } classCatextendsAnimal { publicvoidmiaomiao() { System.out.println(name+"喵喵叫!"); } } publicclassTest_1 { publicstaticvoidmain(String[] args) { Animalanimal1=newDog();//向上转型animal1.name="汪汪"; animal1.age=3; animal1.sleep(); Animalanimal2=newCat();//向上转型animal2.name="喵喵"; animal2.age=5; animal2.sleep(); } }
代码里我们可以看到,通过animal1和animal2的引用发生向上转型,同时去给父类中成员赋值和调用方法,这里代码能正常跑起来,但是当我们去调用子类中特有的方法,程序就会报错,由此我们可以得出一个结论:当发生向上转型之后,此时通过父类的引用只能访问父类自己的成员,不能访问到子类特有的成员!!
向上转型也是发生多态的前提!
向上转型的另外2中写法
1)方法传参
publicclassTest_1 { publicstaticvoidfun(Animalanimal){ } publicstaticvoidmain(String[] args) { Dogdog=newDog(); fun(dog); //这里也发生了向上转型,通过方法的传参 } }
2)方法的返回值
publicstaticAnimalfun1(){ returnnewDog(); }//通过方法的返回值发生向上转型
接下来我们要介绍重写:
👜发生重写,必须满足三个条件:
- 方法名称相同
- 参数列表相同
- 返回值相同
例如:
classAnimal { publicStringname; publicintage; publicvoidsleep() { System.out.println(name+"正在睡觉!"); } } classDogextendsAnimal { publicvoidwangwang() { System.out.println(name+"汪汪叫!"); } publicvoidsleep(){ System.out.println(name+"重写了父类的sleep!");//发生了重写 } } classCatextendsAnimal { publicvoidmiaomiao() { System.out.println(name+"喵喵叫!"); } } publicclassTest_1 { publicstaticvoidmain(String[] args) { Animalanimal1=newDog(); animal1.name="汪汪"; animal1.age=3; animal1.sleep(); }
通过运行结果我们可以看到,这里执行的是子类中的方法,这里其实发生了一个动态绑定,它的意思就是Java在编译的时候识别的是父类中的方法,但是在运行的时候绑定到了子类的方法,所以打印出来的结果也就是子类中的结果!
👜发生动态绑定的三个前提:
向上转型
重写
父类和子类有相同的重写方法名
关于动态绑定,大家可以参考这位大佬的blog: 动态绑定和静态绑定!
1.4多态的特性
1. 消除类型之间的耦合关系
2. 可替换性
3. 可扩充性
4. 接口性
5. 灵活性
6. 简化性
🎉总结
我们来看一下发生多态的完整代码
classAnimal { publicStringname; publicintage; publicvoidsleep() { System.out.println(name+"正在睡觉!"); } } classDogextendsAnimal { publicvoidwangwang() { System.out.println(name+"汪汪叫!"); } publicvoidsleep() { System.out.println(name+"正在玩耍"); } } classCatextendsAnimal { publicvoidmiaomiao() { System.out.println(name+"喵喵叫!"); } publicvoidsleep() { System.out.println(name+"正在和别的猫玩耍"); } } publicclassTest_1 { publicstaticvoidfunction(Animalanimal) { //发生了多态animal.sleep(); } publicstaticvoidmain(String[] args) { Animalanimal1=newDog(); animal1.name="汪汪"; function(animal1); Animalanimal2=newCat(); animal2.name="喵喵"; function(animal2); } }
上述代码中可以领悟到多态的思想,在function方法中的sleep行为,我们并不知道这一行为是由哪个对象去执行的,但是我们可以确实当你主方法中给function传参,传的是哪个对象,就执行哪个对象的方法所表现出来的行为,这就相当于一个接口,每个人都可以去使用它,但是每个人所想要的东西都不一样,正如前面给大家举的例子,榨汁机就相当于一个接口,你放什么水果进去,所榨出来的东西是不一样的,也就是所表现出来的行为不一样,这就是多态,多态的美妙之处!!!
多态是Java中一个重要的思想,如对上文有意见或者有错误,还请大佬们斧正,觉得有帮助的童鞋们,创作不易,蟹蟹三连!