写点什么

Java--- 多态

  • 2022 年 5 月 13 日
  • 本文字数:2143 字

    阅读完需:约 7 分钟

======


重写(override)也称为覆盖,重写是子类对父类非静态,非 private 修饰,非 final 修饰,非构造方法等的实现过程进行重新编写,返回值和形参都不能改变,即外壳不变,核心重写。重写的好处在于子类可以根据需要定义特定于自己的行为,也就是说子类能够根据需要实现父类的方法。


方法重写规则:


· 子类重写父类方法时,一般必须与父类方法原型保持一致:修饰符 返回值类型 方法名(参数列表)要完全一致


· JDK7 以后,被重写的方法返回值类型可以不同,但是必须具有父子关系


· 访问权限不能比父类父类中被重写的方法的访问权限低。


. 父类中被 static private 修饰的方法,构造方法都不能被重写


· 重写的方法可以用 @Override 注解来显示指定


重写和重载的区别:


<table border="1" cellpadding="1" cellspacing="1" style="width:500px;"><tbody><tr><td>区别</td><td>重载</td><td>重写</td></tr><tr><td>参数列表</td><td>必须修改</td><td>不能修改</td></tr><tr><td>返回类型</td><td>可以修改</td><td>不能修改</td></tr><tr><td>访问限定符</td><td>可以修改</td><td>不能做更严格的限定</td></tr><tr><td>异常</td><td>可以修改</td><td>可以减少或删除,一定不能抛出新的或更广的异常</td></tr></tbody></table>


即:方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现


重写的设计规则:


对于已经投入使用的类,尽量不要进行修改,最好的方式是,重新定义一个类,来重复利用其中共性的内容,并且添加或者改动新的内容


**静态绑定:**也称为前期绑定(早绑定),即在编译时,根据用户所传递实参类型确定具体调用哪个方法。典型代表:重载


**动态绑定:**也成为后期绑定(晚绑定),即在编译时,不能确定方法的行为,需要等到程序运行时才能够确定调用哪个类的方法


4. 向上转型和向下转型


=============


4.1 向上转型




向上转型:就是创造一个子类对象,将其当成父类对象来使用


语法格式:父类类型? 对象名? =? ?new? ? 子类类型();


Animal animal = new Cat("糯米",1);


animal 是父类类型,但可以引用一个子类对象,因为:子类对象是一个父类对象,即可以将一个子类对象当成父类对象来引用。因此:向上转型是安全的,因为是从小范围向大范围的转换。


猫和狗都是动物,因此子类对象转化为父类引用是合理的。


**使用场景:**直接赋值? ? ?方法传参? ? ?方法返回


public class TestAnimal {


//方法传参:形参为父类类型引用,可以接受任意子类对象


public static void eat(Animal a){


a.eat();


}


//作为返回值:返回任意子类对象


public static Animal buyAnimal(String var){


if("狗" == var){


return new Dog("小七",2);


}else if("猫" == var){


return new Cat("汤圆",1);


}else{


return null;


}


}


public static void main(String[] args) {


Animal dog = new Dog("旺财",2); //直接赋值:子类对象赋给父类对象


Aniaml cat = new Cat("糯米",1);


eat(dog);


eat(cat);


Animal animal = buyAnimal("狗");


animal.eat();


animal = buyAnimal("猫");


animal.eat();


}


}


运行结果:



向上转型的优点:让代码实现更简单灵活


向上转型的缺陷:不能调用到子类特有的方法?


4.2 向下转型




将一个子类对象向上转型之后当成父类方法使用,再无法调用子类的方法,但有时候可能需要调用子类特有的方法,此时:将父类引用再还原为子类对象即可,即向下转型


public class TestAnimal {


public static voi 《一线大厂 Java 面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】 d eat(Animal a){


a.eat();


}


public static void main(String[] args) {


Dog dog = new Dog("旺财",2);


Cat cat = new Cat("糯米",1);


Animal animal = dog;


animal.eat();


// animal.bark(); 编译器报错,Animal 类中没有 bark 方法


dog = (Dog)animal;


dog.bark();


animal = cat;


animal.eat();


// animal.mew(); 编译器报错,Animal 类中没有 mew 方法


cat = (Cat)animal;


cat.mew();


}


}


向下转型不安全,万一转型失败,运行就会抛异常。Java 中为了提高向下转型的安全性,引入了 instanceof,如果该表达式为 true,则可以安全转换?


public class TestAnimal {


public static void eat(Animal a){


a.eat();


}


public static void main(String[] args) {


Dog dog = new Dog("旺财",2);


Cat cat = new Cat("糯米",1);


Animal animal = dog;


animal.eat();


animal = cat;


animal.eat();


if(animal instanceof Dog){


dog = (Dog)animal;


dog.bark();


}


if(animal instanceof Cat){


cat = (Cat)animal;


cat.mew();


}


}


}


5. 多态的优缺点


==========


优点:


1. 能够降低代码的“圈复杂度”,避免使用大量的 if-else


假如我们现在要打印多个形状而不是一个形状


public static void drawShapes(){


Ret ret = new Rect();


Cycle cycle = new Cycle();


Flower flower = new Flower();


String[] shapes = {"cycle","ret","flower","cycle","flower"};


for(String shape : shapes){


if(shape.equals("cycle")){


cycle.draw();


}


if(shape.equals("ret")){


ret.draw();


}


if(shape.equals("flower")){


flower.draw();


}


}


}


如果使用多态,代码更简单:


public static void drawShapes(){


Shape[] shapes = {new Cycle(),new Rect(),new Cycle(),new Flower()};


for(Shape shape : shapes){


shape.draw;


}

用户头像

还未添加个人签名 2022.04.13 加入

还未添加个人简介

评论

发布
暂无评论
Java---多态_Java_爱好编程进阶_InfoQ写作社区