多态
简单来说呢,多态其实具有表现多种形态能力的特征。专业点的说法是:同一个实现接口,使用不同的实例而执行不同的操作(可以理解为一个爸爸有多个儿子,儿子们做一件事时(操作一个方法),处理的结果不同)。话不多说上代码:
/** * 先写一个宠物类 * @author GMZ * */ public class Pet { protected String name; protected Integer health; public Pet(String name, Integer health) { this.name = name; this.health = health; } public void run(){ System.out.println(name+"----->再跑!"); } }
/** * 写一个狗类继承宠物类 * @author GMZ * */ public class Dog extends Pet{ public Dog(String name, Integer health) { super(name, health); } @Override public void run(){ System.out.println(super.name+"----->子类中跑!"); } }
public static void main(String[] args) { //正常实例对象 Dog dog1=new Dog("lily",100); dog1.run();//输出结果为子类的重写方法 //向上转型 Pet dog=new Dog("旺旺",100); dog.run();//输出结果为子类的重写方法 //向下转型
Dog dog2 = (Dog)dog; System.out.println("判断dog1对象是否是Pet类型--->"+(dog1 instanceof Pet));//打印为true }
子类到父类的转换(向上转型)
如同上图代码中向上转型一样,父类的引用指向子类的实例,实例的对象是子类的实例对象但是作为对象的引用用的确实父类。
向上转型是自动转型,例如:每个类都是Object类的子类。这个就跟上面的一样。
向上转型有一些规则:
1.将一个父类的引用指向一个子类的对象,成为向上转型(upcasting),自动进行类的转换。
2.通过父类引用变量调用的方法是子类覆盖或继承父类的方法,不是父类的方法。(它是通过子类调用,而不是父类自己调用)
3.通过父类引用变量无法调用子类特有的方法。
多态最多用的地方还是用父类的引用作为行参,然后达到代码复用的目的。
/** * 先来写一个代理类 * @author GMZ * */ public class PetProxy { //写成静态的方法 //参数是父类的引用 public static void run(Pet pet){ pet.run(); } }
然后在main方法中这样写
。
打印的结果为:大牛----->子类中跑!
通过代码可以知道,只要是它的子类实例都可以作为参数执行这个方法,不同的实例,会通过run执行不同实例重写或没重写的方法。(父类也可以作为方法的返回值类型,同时也是一种多态在代码中的一种运用)
父类到子类的转换(向下转型)
由于向上转型中父类引用的对象,无法调用子类中特有的方法,那么我们就需要了向下转型。
将一个指向子类的对象的父类引用赋给一个子类的引用(如代码中所示)。成为向下转型。此时必须进行强制类型转换。当这个类的不能被转换时报错为:ClassCastException。
instanceof运算符
instanceof该运算符是用来判断一个对象是否属于一个类(可以是父类,父类的父类,父类的父类的父类)或者实现了一个接口,结果为true或者false。在强制类型转换可以通过instanceof去检查对象的真实类型,再去进行类型转换,避免发生类型转换错误。