欢迎来到南方有乔木的博客!!!
博主主页:点击点击!戳一戳!!
博主名:南方有乔木呀
博主简介:
一名在校大学生,正在努力学习Java语言编程。穷且意坚,不坠青云之志,希望能在编程的世界里找到属于自己的光。
希望帅气or美丽的朋友们能够帮我点赞! 请对文中内容请多多指教!!!
目录
一.什么是多态
概念:
对象去完成某个具体的行为,不同的对象去完成时会产生不同的形状。通过基类的引用来调用重写后的方法,基类的引用可以引用不同子类的对象。
示例:
1.完成打印机打印的行为时,黑白打印机可以打印出黑白的黑白印,彩色打印机可以打印出彩色效果的彩印。
2.再比如,对于吃饭这件事,不同的动物去做会产生不同的效果,狗去晚饭,吃的是骨头,猫去吃饭,吃的是鱼。
总结:不同对象完成打印行为,产生不同的效果与状态,这就是多态。
代码示例:
package demo;
//动物父类
class Animal {
protected String name;
protected int age;
public Animal(String name,int age){
this.name=name;
this.age=age;
}
public void eat(){
System.out.println("吃饭!");
}
public void sleep(){
System.out.println("睡觉!");
}
}
//狗子类继承动物类
class Dog extends Animal{
public Dog(String name,int age){
super(name,age);
}
public void eat(){
System.out.println("吃骨头啦!");
}
public void sleep(){
System.out.println("睡觉呼呼呼!");
}
}
//猫子类继承动物类
class Cat extends Animal{
public Cat(String name,int age){
super(name,age);
}
public void eat(){
System.out.println("吃鱼!");
}
public void sleep(){
System.out.println("睡觉ZZZ~~~!");
}
}
//多态实现
public class Test {
public static void eat(Animal a) {
a.eat();
}
public static void main(String[] args) {
Dog dog=new Dog("大胖",3);
Cat cat=new Cat("阿毛",2);
//同一个方法,不同对象产生不同形态的行为
eat(dog);
eat(cat);
}
}
多态的实现需要三大条件:
- 必须要在继承体系下
- 子类必须要对父类方法中进行重写
- 有父类引用调用重写的子类对象方法
在完成以上的三大条件以后,多态可以就可以得到实现,就像以上的代码示例,当传入狗类对象时,调用eat()方法,会显示出不同的行为,狗的吃的行为是吃骨头,猫的行为是吃鱼。
多态的体现总结:
当代码运行时,当传递不同的对象时,会调用对应类中的方法。多态体现一定是在运行阶段,而不是在编译阶段,编译检测的是语法问题,主要是检测是否违反语法,比如,所调用的方法该类是否存在,存在,则编译成功,不存在,或者参数传递错误,编译报错。
二.什么是重写
多态的三大条件之一之中有子类必须对父类中的方法进行重写,这一条件,下面再跟随博主来总结一下,什么是重写吧。
重写概念:
重写是子类对父类方法的重写。(重写也是在继承体系下进行的)。
且重写的方法不能是static修饰,private修饰,final修饰,此外,构造方法也不能重写。
@Override注解:
在重写时,我们可以使用 @Override这个注解来表示我们的重写,这个注解可以提供合法性校验,如过在重写时有操作失误没有重写成功,那么它会编译报错,给我们提示没有重写成功。
重写示例:
//动物父类
class Animal {
protected String name;
public void eat(){
System.out.println("吃饭!");
}
//狗子类继承动物类
class Dog extends Animal {
@Override
public void eat() {
System.out.println("吃骨头!");
}
}
//猫子类继承动物类
class Cat extends Animal {
@Override
public void eat() {
System.out.println("吃鱼!");
}
在重写时,将父类方法的内容拷贝一份在子类中对内容进行重写即可。或者,在idea中使用快捷键Ctrl+O,选中要重写的方法。
多态重写的注意事项:
- 子类对父类的方法进行重写时,子类的访问限定符不能比父类的的权限低。比如,父类的访问限定符是:protected,那么,子类只能是public,或者protected权限,不能比父类中的权限低。
- 子类的方法名,参数列表必须和父类的方法名参数列表一致,返回值可以不同,但是,返回值类型如果不同,那么,返回类型必需具有继承的父子关系。
三.重写与重载的区别
区别:
- 方法名称一致
- 方法重写参数列表一定不变,重载参数列表必须改变,因为重载的概念就是,方法名相同,参数列表不同形成重载。
- 重写的返回值类型一定不能修改(但是继承体系下构成父子关系的除外),方法重载返回值类型可以修改.
四.多态的优点与缺点
优点:
1.多态可以省略了一些不必要的if-else语句,使代码更加简洁,易懂,如果不使用多态,那么有不同的对象进行同一个行为时,就需要很多的分支语句if-else语句来进行选择,不利于对代码的解读与理解,因此,多态可以省略很多不必要的分支。
2.多态的可扩展性更强。如果需要增加一个新类型,那么,只需要增加一个新的类就行了。不需要做出很大的改动。
缺点:
1.多态虽然使代码更加容易理解,但是,多态会使得程序的运行效率降低,因为多态还需要传递参数,判断调用哪些对应的方法。
五.向上转型和向下转型
向上转型
概念:创建一个子类对象,将子类对象转换为父类来引用
1.比如,有一个形状类,圆形,矩形,三角形继承图形类,创建子类对象三角形/圆形/矩形之后,将它们当作图形类使用,因为三角形/圆形/矩形本身也是图形,和图形类之间是一种is-a的关系。
2.再比如,有一个动物类,狗类和猫类继承动物类,创建狗/猫对象以后将它们当作动物类使用也是可以的,因为狗和猫本身就是动物,和动物类之间也是一种is-a的关系。
所以,将子类对象当作父类对象来使用,这样使用没有什么问题,且是安全的,还可以使代码更加灵活。
向上转型的三大用途:
1.直接赋值
2.方法传参
3.方法返回
向下转型:
概念:将父类对象转换为子类来引用
向下转型用途:当子类对象向上转型为父类对象之后,就无法调用到子类特有的方法,有时候需要用到子类特有的方法,这时候就需要向下转型,将父类对象转换为子类才能调用到子类特有的方法。
向上转型与向下转型时注意:
子类转为父类时是属于自动转型的,父类转为子类要类型强制转换。
向下转型不安全,因为父类对象转为子类,子类可能有多种,父类本身的类型可能不一定与要转型的类型相同,这时候可能会导致转型失败。
示例:
如果有一个父类动物类,一个子类狗类,一个子类猫类,狗类创建一个狗对象,狗对象向上转型为动物类,狗本身是动物,可以自动转换为父类,转换过后动物类的引用指向了狗类,到此完成了向上转型。
如果要完成向下转型,那么动物类就要转换为狗类,但子类有狗类和猫类,转换时可能转换为狗类,也可能转换为猫类,因此,向下转型不安全,也可能失败,因此,设计者使用instanceof关键字来尽量提高向下转型的安全性。因此当向下转型时,可以使用instanceof关键字来判断转换类型。
向上转型和向下转型代码示例:
package demo;
//动物类
class Animal{
protected String name;
protected String gender;
public Animal(String name, String gender) {
this.name = name;
this.gender = gender;
}
public void eat(){
System.out.println("吃饭");
}
}
//狗类继承动物类
class Dog extends Animal{
public Dog(String name, String gender) {
super(name, gender);
}
public void eat(){
System.out.println("吃饭啦啦啦");
}
}
//猫类继承动物类
class Cat extends Animal{
public Cat(String name, String gender) {
super(name, gender);
}
public void eat(){
System.out.println("吃饭呼呼呼");
}
}
public class Test {
public static void main(String[] args) {
Dog dog=new Dog("大胖","公");
Cat cat=new Cat("阿猫","公");
//向上转型
Animal animal=cat;
animal.eat();
//再向下转型
if(animal instanceof Dog){ //若实例化是狗则转化为狗
dog=(Dog)animal;
}
if(animal instanceof Cat){ //若实例化是猫则转化为猫
cat=(Cat)animal;
}
}
}