多态数组
根据父类的引用可以指向子类的对象,可以用父类类型来创建一个数组,里面存放父类和子类的对象
在Person中有say()方法,Student和Teacher类中重写了say()方法
注意此时persons中的每个元素persons[i]的编译类型都是Person,运行类型由创建对象时决定
遍历循环多态数组,调用say方法
因为其它两个类继承了Person类,编译类型都是Person类型,因此可以调用say方法,又由于对象间的运行类型不一样且每个类都重写了say()方法,因此在运行时调用自己类中的say()方法
要是想在遍历中调用对象特有的方法,要加一个判断,判断元素peisons[i]的运行类型是不是子类
用instanceof判断persons[i]是否是Student类或Student类的子类,是的话将persons[i]向下转型,只有将对象的编译类型变成Student类才能调用Student类的study方法。向下转型的语句:1.让另外一个引用指向对象Student student = (Student)persons[i],遍历的时候多次执行该语句,每次让这个对象的引用指向不同的对象地址,再让对象引用调用study()方法; 2.直接将persons[i]向下转型,不用新的引用指向对象,((Student)persons[i]).study() 调用方法即可
多态参数
方法中的参数为(父类 引用名),这样可以传入子类的对象,相当于将父类的引用指向了子类的对象,向上转型
showEmpAnu(Empolyee e)方法中用了一个父类的引用接收实参,实际上是Employee e = new 子类名(),在子类中重写了getAnnual()方法,当调用该方法时,会根据e的运行类型(动态绑定机制)调用子类中的getAnnual()方法。
testwork(Employee e)方法中同样用了父类的引用接收实参,但该方法中要执行的是根据传进来对象的运行类型去调用运行类型类中的方法,用一个if判断将传入的运行类型与不同子类相比较。由于编译类型为Empolyee,因此需要向下转型:(子类名)父类引用名,再调用方法
Object类中的方法
==
在判断基本类型时,判断值是否相等;在判断引用类型时,判断地址是否相等
B bObj向上转型,还是和a指向同一个地址
equals()方法
使用:
equals只能判断引用类型
Integer和String类重写了equals方法
重写后,可以直接用来比较值是否相同,本来时比较两个对象的地址是否相等。
重写equals()方法,可以比较对象的各个属性是否相等
采用向下转型的两种方法
1
2
形参为父类Object obj,可以接收子类对象。this在此的作用是,this代表调用该方法的当前对象。第一步:判断如果两个对象指向同一个地址,毫无疑问对象的各个属性都相等。第二步:判断传入的对象是否为Person类型,是的话就将其进行向下转型(两种方法)来比较,转型后才可调用属性进行比较。字符串类型的属性采用字符串类中重写的equals()方法作比较,别的属性用==比较。
练习
hashCode
toString
重写toString
输出对象默认调用toString方法
finalize方法
当对象某有任何引用时,即没有引用指向对象的地址时,jvm会认为该对象是个垃圾