1.多态的概念
就是多种形态,具体点就是去完成某个⾏为,当不同的对象去完成时会产⽣ 出不同的状态。
通过父类引用,调用父类和子类同名的方法,此时就会发生动态绑定,我们把这种思想称之为多态。
多态实现条件 在Java中要实现多态,必须要满⾜如下⼏个条件,缺⼀不可:
1. 必须在继承体系下
2. ⼦类必须要对⽗类中⽅法进⾏重写
3. 通过⽗类的引⽤调⽤重写的⽅法
结论:
4.可以发生动态绑定
5.借助动态绑定,就可以发生多态
public static void eatfunc(Animal animal){ animal.eat(); } //animal这个引用,引用的对象不一样 //调用同一个方法eat,表现的行为不一样,所以把这种形态叫做多态2.重写
重写(override)规则:
满足方法名称相同、参数列表相同(个数、类型、顺序)、返回值相同
对于方法的访问修饰符来说,子类的权限一定要大于等于父类的权限:
public > protected > 包访问权限 > private
对于private修饰的方法,子类没法重写
被static修饰的方法,子类没法重写
被final修饰的方法,子类没法重写,此时表示该方法不能被重写
构造方法也是不能被重写的
public void eat(){ System.out.println(this.name+"正在吃饭..."); } public void eat() { System.out.println(this.getName()+"正在猫粮..."); } public void eat() { System.out.println(this.getName()+"正在狗粮..."); }协变类型:
被重写的返回值类型可以不同,但是必须是具备父子关系的
public Animal eat(){ System.out.println(this.name+"正在吃饭..."); } public Cat eat() { System.out.println(this.getName()+"正在猫粮..."); }复习重载(overload):
方法名相同、参数列表不同(个数、顺序、数据类型)、返回值不要求
【重写和重载的区别】:
⽅法重载是⼀个类的多态性表现,⽽⽅法重写是⼦类与⽗类的⼀种多态性表现。
静态绑定:
也称为前期绑定(早绑定),即在编译时,根据⽤⼾所传递实参类型就确定了具体调⽤那个⽅ 法。典型代表函数重载。
动态绑定:
也称为后期绑定(晚绑定),即在编译时,不能确定⽅法的⾏为,需要等到程序运⾏时,才能 够确定具体调⽤那个类的⽅法。
3.向上转型和向下转型
①.向上转型操作
向上转型:实际就是创建⼀个⼦类对象,将其当成⽗类对象来使⽤。
public class test { public static void main(String[] args) { Animal animal =new dog("旺财",10); } //父类的引用引用子类对象public void eatFunc(Animal animal){ } public static void main(String[] args) { dog dog = new dog("旺财",10); eatFunc(dog); cat cat = new cat("咪咪",2); eatFunc(cat); } //参数的传递public static Animal func(){ return new cat("咪咪",2); } //作为返回值向上转型的优点:让代码实现更简单灵活。
向上转型的缺陷:不能调⽤到⼦类特有的⽅法。
②向下转型
将⼀个⼦类对象经过向上转型之后当成⽗类⽅法使⽤,再⽆法调⽤⼦类的⽅法,但有时候可能需要调 ⽤⼦类特有的⽅法,此时:将⽗类引⽤再还原为⼦类对象即可,即向下转换。
实际就是把父类类型给到子类类型,但是不安全,像下面这个例子,为什么编译器要强制转换才能不报错,因为不是所有的动物都是狗。
dog dog = new dog("旺财",10); //父类类型给到子类类型 dog dog = (dog)animal; dog.bark();向下转型⽤的⽐较少,⽽且不安全,万⼀转换失败,运⾏时就会抛异常。Java中为了提⾼向下转型的 安全性,引⼊了 instanceof ,如果该表达式为true,则可以安全转换。
public class TestAnimal { public static void main(String[] args) { Cat cat = new Cat("元宝",2); Dog dog = new Dog("⼩七", 1); // 向上转型 Animal animal = cat; animal.eat(); animal = dog; animal.eat(); if(animal instanceof Cat){ cat = (Cat)animal; cat.mew(); } if(animal instanceof Dog){ dog = (Dog)animal; dog.bark(); } } }如果之前这个引用引用的对象和你向下转型转给的类型
Shape[] shapes = {new Cycle(),new Rect(),new Cycle(),new Rect(),new Flower()}; //这就叫匿名对象 //特点:这个对象只能使用1次