目录
一、多态的概念
多态简单来说,就是一种事物,多种形态。具体一点就是去完成某个行为,当不同的对象去完成的时候就会产生出不同的形态。
举个例子:
小猫和小狗都是属于动物类的一种,而小猫和小狗属于不同的对象都是使用到了animal的eat()方法,而且会有不同的结果。
总的来说,同一个事情,发生在不同对象身上,会有不同的结果。
二、多态要点——重写
在多态里面重写是一个很重要的东西,那么重写是什么呢?重写我们也叫覆盖,是子类对父类的非final、private、非构造方法等进行重新编写。
重写返回值和参数必须要相同,内容不同。重写的好处就是,子类可以根据需要,重写父类的内容。
重写注意事项:
1、首先是子类重写父类的方法时,返回值类型以及方法名(只有内容改变)要一致。
2、访问权限不能比父类的权限更低,比如,父类是public修饰,那么子类不能声明为protected。
3、父类被static和private修饰的方法、构造方法都不能被重写。
4、重写的方法可以用@Override来指定,如果没有成功被重写则会报红
那么重写和重载有什么区别呢?
首先是重写的参数列表和返回类型一定不能修改(除非可以构成父子关系,否则返回类型一定不能被修改),访问限定符也要严格限制,而重载的参数列表一定要修改,返回类型和访问限定符可以被修改
三、多态实现条件
1、首先必须要在继承体系下
2、子类必须要对父类种方法进行重写
3、通过父类的引用调用重写的方法
代码如下:
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+"吃饭");
}
}
public class Cat extends Animal{
public Cat(String name,int age){
super(name,age);
}
@Override
public void eat() {//对父类的eat方法进行重写
System.out.println(name+"正在吃猫粮");
}
}
public class Dog extends Animal{
public Dog(String name,int age){
super(name,age);
}
@Override
public void eat() {//对父类的eat方法进行重写
System.out.println(name+"正在吃狗粮");
}
}
public class Test {
public static void eat(Animal a){
a.eat();
}
public static void main(String[] args) {
Dog dog=new Dog("旺财",2);
Cat cat=new Cat("咪咪",1);
eat(dog);
eat(cat);
}
}
四、向上转型、向下转型
学到多态,我们就必须要知道向上转型和向下转型的东西,那么何为向上转型,何为向下转型?向上转型,就是利用父类实例子类的对象,然后子类可以使用父类的东西,向下转型则相反,就是利用子类实例父类的对象,然后父类可以使用子类的东西,但是有一个缺点,就是有可能会转型失败,因为子类继承父类的东西,修饰符范围父类有可能比子类低,所以可能转型会失败。
以代码为例子:
public class Animal {
String name;
int age;
public void eat(){
System.out.println(this.name+"正在吃粮食");
}
public void run(){
System.out.println("正在跑");
}
}
public class Cat extends Animal{
public Cat(String name,int age){
this.name=name;
this.age=age;
}
public void eat(){
System.out.println(this.name+"正在吃猫粮");
}
}
public class Dog extends Animal{
public Dog(String name,int age){
this.name=name;
this.age=age;
}
public void eat(){
System.out.println(this.name+"正在吃狗粮");
}
public void swim(){
System.out.println(this.name+"正在游泳");
}
}
public class Test {
public static void main(String[] args) {
Animal dog=new Dog("旺财",1);//通过父类实例化子类对象可以直接使用子类的
dog.run();
dog.eat();
}
}
打印结果如下:
图1
通过向上转型,被实例化的子类可以直接调用父类的东西,run()方法是在子类没有的,但可以直接使用父类的。
那么向下转型是怎么样的呢?以上面的类为例子。
public class Test {
public static void main(String[] args) {
Animal dog=new Dog("旺财",1);
((Dog)dog).swim();//向下转型然后得到子类中父类没有的方法
// dog.swim();调用不到,因为dog向上转型只能使用到父类的东西
dog.run();
dog.eat();
}
}
打印结果如下:
图2
我们要知道,向上转型之后,子类只能使用父类的方法,那么我们该如何调用到子类的东西呢?那么就只能把父类看成子类,把子类看成父类,这种向下转型就能做到,通过向下转型又能使用到自己的东西,但必须要注意的是,向下转型不一定转型成功,有可能会转型失败。
五、动态绑定
动态绑定是什么呢?在向上转型那里,我们知道子类可以使用到父类的内容,但如果子类重写过父类的东西,那么子类通过引用父类方法得到的结果确实子类方法的结果,什么意思呢?看图2,我们知道Animal类里面的eat方法是吃饭,但通过动态绑定使用到了Dog类重写的方法,也就是“旺财正在游泳”,那么这就叫做动态绑定。