多态:多种形态,就是去完成某个行为,不同对象去完成时会产生不同的状态。
多态体现:当代码运行时,当传递不同类对象时,会调用对应类中的方法。

可能刚开始看这张图片不是很能理解,接下来会进行对向上转型和重写的讲解,看完在回头看这张代码,我相信你能更清晰的理解他们。
优点:
缺点:
向上转型:实际就是创建一个子类对象,将其当成父类对象来使用

父类类型 对象名 =new 子类类型
public class Test {
public static void main(String[] args) {
Animal animal=new Dog(2,"小乖");
}public static void main(String[] args) {
Dog dog = new Dog(2,"小乖");
func(dog);
}
public static void func(Animal animal){
}public static void main(String[] args) {
Animal animal=func2();
}
public static Animal func2(){
Dog dog = new Dog(2,"小乖");
return dog;
}优点:让代码实现更简单灵活;
缺点:通过父类的引用,调用父类是无法直接调用的,只能调用父类自己的。
向下转型:将父类引用在还原为子类对象

子类类型 类型名=(子类类型)父类类型名;
先通过向上转型,在进行强制类型转换

由上述代码,可以得出,向上转型是向下转型的基础。
如果我在加一个父类的子类猫类。先将狗向上转型为动物,再将其向下转型为猫类,这样是否可以?

结果告诉我们不是所有的向下转型都可以的

上面两种的区别就是,一个本身就是Dog,而另一个是Dog不是Cat。
为了预防这种情况,我们可以使用instanceof来验证
instanceof是引用的意思
public static void main(String[] args) {
Animal animal1=new Dog(3,"小黄");
if(animal1 instanceof Cat){
System.out.println("引用了猫");
}
else{
System.out.println("没有引用");
}
重写:也称为覆盖。重写是子类对父类非静态、非private修饰,非final修饰,非构造方法等的实现过程进行重新编写。可以理解为子类对父类方法的覆盖。

如果我们调用animal的fun,其结果又是什么?

我们发现他调用的是子类的重写的方法,这种叫做动态绑定。
动态绑定:在继承的情况下,当代码运行的时候,通过父类引用,调用父类和子类的重写的方法,结果实际调用了子类的方法。
注意事项:

既然有了动态绑定,那么应该也有静态绑定吧。
静态绑定:也称为前期绑定(早绑定),即在编译时,根据用户所传递实参类型就确定了具体调用方法。典型代表函数重载。
public static void main(String[] args) {
int a=1;
int b=2;
int c=3;
int ret=add(a,b);
System.out.println(ret);//3
}
public static int add(int a,int b){
return a+b;
}
public static int add(int a,int b,int c){
return a+b+c;
}调用几个参数,你就知道用确定了调用的是那个方法





所以方法重载是一个类的多态性表现,而方法重写是子类和父类的一种多态性表现。
什么时候使用重写?
对于已经投入使用的类,进行不要修改。最好的方式就是:重新定义一个新的类,来重复利用其中共性的内容并添加或改动新的内容。例如:软件的功能的改进,我们不在原来老的类进行改进,因为原来的软件,用户还在使用。于是我们新建一个类,对这个改进的方面进行重写就好了
为什么这么说呢?
1.首先我构建了一个父类Animal和子类Dog,在父类和子类写了fun()重写方法并在父类的构造方法中调用了子类和父类的重写方法。实例化后,我得出的结果是父类的被重写方法还是子类对父类的重写方法?我在父类的构造方法中调用父类的方法,结果应该是调用父类的方法吧。

但结果是子类的构造方法
2.既然我都知道了,在父类构造方法中调用子类和父类的重写方法会发生动态绑定,调用的是子类的重写方法,那么我将子类的代码修改成下面的代码
public class Dog extends Animal{
int num=1;
public void fun() {
System.out.println(num);
}
}其实例化后结果会是什么?1吗?

但结果是0,为什么?
这就考察到了代码块的顺序,我们知道代码块的顺序是先执行父类和子类静态代码块顺序,在父类的实例和构造在子类的实例和构造。
