Java多态
1.多态
1.1 多态的概念
多态,通俗来说,就是多种形态。总的来说,就是同一件事情,发生在不同的对象身上,就会产生不同的结果。
比如,同一个老师给学生上课,翠花的成绩特别优秀,小明虽然成绩不行吧,但是小明游戏玩的还不错,先不考虑有点气人这一点,这怎么不算是一种成绩呢。
1.2 多态实现条件
在Java中要实现多态,必须要满足以下几个条件,缺一不可:
- 必须在继承体系下
- 子类必须要对父类中的方法进行重写
- 通过父类的引用调用重写的方法
多态体现:在代码运行时,当传递不同的对象时,会调用对应类中的方法
//Animal类
public class Animal {
String name;
int age;
public Animal(String name, int age){
this.name = name;
this.age = age;
}
public void eat(){
System.out.println(name + "吃饭");
}
}
//继承了Animal的cat类
public class Cat extends Animal{
public Cat(String name, int age){
super(name, age);
}
@Override
public void eat() {
System.out.println(name + "吃鱼");
}
}
//继承了Animal的dog类
public class Dog extends Animal{
public Dog(String name, int age){
super(name, age);
}
public void eat(){
System.out.println(name + "吃骨头");
}
}
//测试类
public class TestAnimal {
public static void eat(Animal a){
a.eat();
}
//编译器在编译代码时,并不知道要调用Dog 还是Cat 中的eat方法
//等程序运行起来后,形参a引用父类的具体对象确定后,才知道调用哪个方法
public static void main(String[] args) {
Cat cat = new Cat("小猫",2);
Dog dog = new Dog("小狗",1);在这里插入图片描述
eat(cat);
eat(dog);
}
}
首先我们写了四个类:
Animal , 继承了Animal的cat, 继承了Animal的dog
Animal、cat、dog这三个类中都有eat这个方法
还写了一个测试类TestAnimal类,这个类里面也有eat方法,并且需要注意的是,这个eat方法的参数是Animal类型,这就说明这里我们可以传的有三个选项,Animal可以传,由于cat和dog它们继承了Animal类,所以这两个类我们也可以传它们的对象.
public static void eat(Animal a){
a.eat();
}
大家看到这样的一个参数不要觉得很复杂,其实跟我们平时经常用的 int 和 String 没什么不一样,不要被它的样子唬住了.
这个方法编译器在编译代码时,并不知道要调用的是哪个类里面的eat,当程序运行起来,形参 a 引用的具体对象确定后,才知道要调用哪个方法,需要注意的是,此处的形参类型必须是父类类型才可以.
Cat cat = new Cat("小猫",2);
Dog dog = new Dog("小狗",1);
eat(cat);
eat(dog);
上面的这几行代码分别传了三个不同类的对象,我们可以来看一下此处代码的运行结果:
由于 a 引用不同的实例调用eat方法可能会有多种不同的表现,这种行为就称为多态。
1.3 重写
重写(override):也成为覆盖。重写是子类对父类非静态、非private修饰、非final修饰,非构造方法等的实现过程进行重新编写,返回值和形参都不能改变。即外壳不变,核心重写!
重写的好处就在于子类可以根据需要,定义自己的行为,也就是说子类能够根据父类的需要实现父类的方法。
【方法重写的规则】
- 子类在重写父类的方法时,一般必须与父类方法原型一致,具体表现在:返回值类型、方法名、参数列表,要完全一致.
- 被重写的方法返回值类型可以不同,但是必须是具有父子关系的.
- 访问权限不能比父类中被重写的方法的访问权限更低. 例如,如果父类方法被public修饰,则子类中重写该方法就不能声明为protected.
- 父类被static、private修饰的方法、构造方法都不能重写.
- 重写的方法,可以使用@Override注解来显式指定. 有了这个注解可以帮我们进行一些合法性校验. 例如,不小心将方法名字拼错了,那么此时编译器就会发现父类中并不存在这个方法,就会编译报错,提示无法构成重写.
【重写和重载的区别】
区别点 | 重写(override) | 重载(overload) |
---|---|---|
参数列表 | 一定不能修改 | 必须修改 |
返回类型 | 一定不能修改(除非可以构成父子类关系) | 可以修改 |
访问限定符 | 一定不能做更严格的限制(可以降低限制) | 可以修改 |
即:方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现.
【重写的设计原则】
对于已经投入使用的类,尽量不进行修改。最好的方式是:重新定义一个类,来重复利用其中共性的内容,并且添加或者改动新的内容。
静态绑定:
也成为前期绑定(早绑定),即在编译时,根据用户所传递实参类型就确定了具体调用哪个方法,典型代表是方法重载。
动态绑定:
也成为后期绑定(晚绑定),即在编译时,不能确定方法的行为,需要等到程序运行时,才能够确定具体调用哪个类的方法。
原文地址:https://blog.csdn.net/2402_83672777/article/details/142500519
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!