动物类(父类)
class Animals {
int a = 0;
public void eat() {
System.out.println("动物吃饭!");
}
public int f(int x, int y) {
return x + y;
}
public static int g(int x, int y) {
return x * y;
}
}
小狗类(子类)
class Dog extends Animals {
int a = 1;
public void eat() {
System.out.println("狗在吃骨头!");
}
public void watchDoor() {
System.out.println("狗看门!");
}
public int f(int x, int y) {
int m = super.f(x, y);
return m + x * y;
}
public static int g(int x, int y) {
int m = x + y;
return m + x * y;
}
}
测试类
public class Test{
public static void main(String[] args) {
/**
* 输出结果:狗在吃骨头!
* 多态的引用,就是向上转型 实例化的是Dog类,创建Animals引用来接受这个实例化对象
* 1、如果Animal中的eat方法在Dog中重写了,那么对象dog在调用eat方法时候,是调用的Dog中重写的eat方法。如果没有重写eat方法,那么会调用Animal中的eat方法。
*
* 总结:无论使用多态实例化对象还是不使用多态实例化对象,调用其中的方法时,都是从子类中先寻找,若没有就逐层向上寻找,直到在祖先类中找到重写的方法。
*/
Animals dog = new Dog();
dog.eat();
/**
* 输出结果:狗看门!
* 像上述Animals dog = new Dog();这种使用多态实例化对象的,jvm会屏蔽掉子类非重写父类的方法,如Dog中的watchDoor方法。
* 如果想要使用watchDoor方法那么就要向下转型。
* 但是这里又有一个注意点:万一这个Dog类不是Animals的子类呢?
* 我们只需要在这里加一个判断if(dog instanceof Animals) 如果是true则可以向下转型,false就不行。
* 转型成功之后既可以使用子类的“私有”(这里的私有方法是指父类中没有的,只有子类自身有的方法)方法
*/
Dog dogDown = (Dog) dog;
dogDown.watchDoor();
/**
* 输出结果是0 1
* 口诀:变量看左。
* 注意:变量无重写!!!
* 变量无重写!!!
* 变量无重写!!!
*/
System.out.println(dog.a);
System.out.println(dogDown.a);
/**
* 输出结果都是11
* 因为子类Dog重写了父类Animals的方法。
* 口诀:方法看右
*/
System.out.println(dog.f(1, 5));
System.out.println(dogDown.f(1, 5));
/**
* 输出结果是6 11
* 注意:静态方法没有重写这一个说法。
* 所以在dog中调用g方法,dog是向上转型成Animal类,所以只会去访问Animals这个子类的g方法。
* 而dogDown进行了向下转型,所以只会调用dogDown中的g方法。
* 重要的事情说三遍:
* 静态方法无重写!!!
* 静态方法无重写!!!
* 静态方法无重写!!!
*/
System.out.println(dog.g(2,3));
System.out.println(dogDown.g(2,3));
}
}