多态的实现、向上转型,重载与多态的关系
向上转型
向上转型的前提时存在继承,是父类与子类之间的关系。
语法格式
父类类型 对象名=new 子类类型();
安全性:由于子类与父类之间的关系是 is a 的关系,比如说猫是一个动物,所以说把子类归纳于父类的一个对象,是没有问题的,因此是安全的。
public class Animal {
String name;
int age;
public void eat(String name){
System.out.println(this.name+"在吃饭饭!");
}
public void sleep(String name){
System.out.println(this.name+"在睡觉觉!");
}
}
public class Cat extends Animal{
public Cat(String name){
this.name=name;
}
public void bark(String name){
System.out.println(this.name+":喵喵喵");
}
}
public class Polymorphic {
public static void main(String[] args) {
Animal cat=new Cat("玛卡巴卡");//向上转型
cat.eat("玛卡巴卡");
//cat.bark("玛卡巴卡");无法访问子类中特有的方法;
cat=(Cat)cat;//向下转型
((Cat) cat).bark("玛卡巴卡");//可以访问特有方法;
}
}
运行结果:
将一个子类向上转型当成父类使用时,子类当中特有的方法无法继续使用,因此要采用向下转型,将父类转换为子类,从而进行访问,实现类似于类型的强转:
相反的来说向下转型:即把父类对象当成一个子类对象,反过来说并不是所有的动物都是猫,因此是不安全的。
使用场景
直接传参
public static void main(String[] args) {
Animal cat=new Cat("玛卡巴卡");
}
方法传参
public class Polymorphic {
public static void eatfood(Animal animal){
animal.eat();
}
public static void main(String[] args) {
Animal cat=new Cat("玛卡巴卡");
eatfood(cat);
}
}
方法返回(返回任意子类对象)
public static Animal buyAnmimals(String kinds){//Animal 为返回值类型
if(kinds="猫"){
return new Cat("猫咪",3);//匿名对象
}
if(kinds="狗"){
return new Dog("狗狗",2);
}
重写
重写是子类对父类的重写,是父类一个多态化的表现。
public class Animal {
String name;
int age;
public void eat(){
System.out.println(this.name+"在吃饭饭!");
}
}
public class Cat extends Animal{
public Cat(String name){
this.name=name;
}
@Override
public void eat() {//函数名返回值及参数均相同
System.out.println(this.name+"在吃猫粮");
}
}
public class Dog extends Animal{
public Dog(String name){
this.name=name;
}
@Override
public void eat() {//函数名返回值及参数均相同
System.out.println(this.name+"在吃狗粮");
}
public void bark(){
System.out.println(this.name+":汪汪汪");
}
}
在程序编译时,并不知道确定的方法行为,在程序运行时才能具体确定调用哪个类的方法(子类对象重写了父类对象中的方法),这也就是动态绑定:
动态绑定(重写)
特点:
向上转型(父类引用引用子类对象);
通过父类引用调用与子类中的覆盖方法;
静态绑定(重载)
即在编译时用户传递的参数就能确定调用哪个方法;
重载与重写
重载的特点
一、函数名相同;
二、参数列表不同(参数个数,参数类型);
三、返回值不做要求;
重写的特点
一、函数名相同;
二、参数列表相同(参数个数,参数类型);
三、返回值相同;
重写注意事项
子类的访问权限必须小于等于父类的访问权限;
被static,final 修饰的的方法无法被重写;
总结
所谓多态其实是通过一个引用来调用方法后,有多种表现形式。这都建立在动态绑定上。
多态实现的条件
必须是在继承体系的前提下;
子类必须对父类的方法进行重写(动态绑定);
通过父类的引用来调用重写的方法;(父类类型作为函数传参的形参);