面向对象基础10(多态)
多态的定义
同一个类型的多个实例、在执行同一个方法,呈现出多种行为特征。
变态的定义
同一个类型的实例在执行统一个方法,但是个别对象呈现出变异的行为特征。
态的概念不是状态,而是行为。
多态存在的意义
当Java执行方法时,方法的执行是动态绑定的:
方法总师执行该变量实际所指向对象的方法。
例1:
public class Bird {
public void fly(){
System.out.println("Birds Flying");
}
}
class Sparrow extends Bird{
}
class Ostrich extends Bird{
@Override
//用于报错,要求被修饰的方法必须重写父类方法,否则就报错
//重写fly方法
public void fly(){
System.out.println("can not fly");
}
}
public class Polymorphism {
public static void main(String[] args) {
//向上转型
Bird b1=new Sparrow();
Bird b2=new Ostrich();
b1.fly();//动态绑定Sparrow的fly方法
b2.fly();//动态绑定Ostrich中的fly方法
}
}
向上转型:子类对象可以直接赋值给父类对象;
自动完成
向下转型:父类变量赋值给子类变量;
强制转换完成——(类型)变量名
变量的类型
编译时类型:声明该变量指定的类型。
在Java的编译阶段,Java编译器只认编译时类型;
运行时类型(实际类型):该变量实际引用的对象的类型。
强制转换 例2:
class Shape {
public void draw(){
System.out.println("画图");
}
}
class rect extends Shape{
public void info(){
System.out.println("矩形");
}
}
class circle extends Shape{
public void round(){
System.out.println("绕圈");
}
}
public class Transform{
public static void main(String[] args) {
Shape s1=new rect();
/*
在编译时s1是Shape类型不存在info方法
可以运行,但编译器无法调用
*/
Shape s2=new circle();
//此时s2无法调用circle类下的round方法,需要强制转换
circle c=(circle) s2;
c.round();
}
}
只能在具有父子关系之间的变量进行强转,否则会产生编译错误。
如果在具有继承关系的变量进行转化时,如果被转化变量的实际类型不是要转化的目标类型
就会出现异常——ClassCastException
instanceof
运算符的存在就是避免上述异常。
语法:变量名 instanceof 类型
作用:当变量所引用的对象是后面类或子类的实例时,该运算符返回true
该运算符只能在变异类型具继承关系时进行判断,否则会报错
该运算符可以保证:强转换的变量是可以转换的,避免ClassCastException
例:
public class InstenceofTest {
public static void main(String[] args) {
//声明hello时使用Object类,这样Hello的变异类型是Object
//Object是所有类的父类,但hello变量的实际类型是String
Object hi = "hello";
//String和Object类存在继承关系,可以用instanceof进行运算,结果返回true
System.out.println("字符串是否是Object类的实例" + (hi instanceof Object));
System.out.println("字符串是否是String类的实例" + (hi instanceof String));
//Math和Object类存在继承关系,结果返回false
System.out.println("字符串是否是Math类的实例" + (hi instanceof String));
//String实现了Comparable接口,结果返回true
var hello = "hello";
System.out.println("字符串是否是Comparable接口的实例" + (hello instanceof Comparable));
//String类与Math类不存在继承关系,编译无法运行
System.out.println(hello instanceof Math);
}
}
一般的,当向下强制转换类的时候都需要运用instanceof
进行判断