所谓封装,就是让所定义的私有属性(private)只能在本类中访问,并且提供公有的(public)方法对属性进行访问(get)和修改(set)(使用该方法可能也需要一定权限)。
继承,指的是设置一个父类,子类(extends)会继承父类中允许访问的属性和方法(在相同包中,除private外都能访问,在不同包中,默认类型也不能访问)。
多态 ①向上转型,将子类对象转换为父类类型,是自动进行的,因为子类是父类的一种特殊类型,所以可以安全地将子类对象赋值给父类变量。-特点:向上转型后,只能访问父类中定义的方法和属性,无法直接访问子类特有的方法和属性,但可以优先访问子类中重写父类的方法,即类型和参数都相同的方法。
代码如下(父类Animal,子类Dog),Animal animal =new dog(),animal可以访问Animal中的属性和方法,但不能访问子类dog中的特有方法。
②向下转型- 概念:将父类对象转换为子类类型,需要进行强制类型转换。但这种转换并不总是安全的,只有当父类对象实际是子类对象的实例时,向下转型才是合法的。特点:向下转型可以让父类对象访问子类特有的方法和属性,但如果转换不当,会引发 ClassCastException 异常。为了避免这种情况,通常会在向下转型之前使用 instanceof 关键字进行判断。
代码如下(父类Animal,子类Dog),Animal animal =new dog(),Dog dog = (Dog)animal,此时dog可以访问子类Dog中的属性和方法了。
③动态绑定机制(属性没有该机制)
多态中的动态绑定机制是Java实现多态性的关键,以下是其相关介绍:
概念:动态绑定是指在程序运行时,根据对象的实际类型来决定优先调用哪个类的重写方法。
工作原理
- 编译期:在编译阶段,编译器只检查方法调用是否在语法上合法,依据对象引用的类型来确定可调用的方法列表,但并不确定实际调用的是哪个类的方法。
- 运行期:程序运行时,JVM会根据对象的实际类型来动态地选择要调用的方法。具体来说,JVM会在对象所属的实际类及其父类中查找被重写的方法,并调用最符合对象在上述代码中, animal1 和 animal2 虽然被声明为 Animal 类型,但在运行时,根据它们实际指向的 Dog 和 Cat 对象,动态地调用了各自类中重写的 makeSound 方法。实际类型的那个方法。
即当在父类中遇到了子类中也有的方法(重写)时,此要看它的运行类型,如果运行类型为子类,则运行子类中的方法。
总之就是在子类中有重写方法,不管是在父类还是子类中的方法,优先查找运行类型所在的类的方法进行调用,若该类中没有该方法则在父类或子类中进行查找。
在这三种特性中,对this和super的使用十分重要,this主要是访问本类中的属性和方法,super主要是访问父类中的属性和方法,仔细来说,①(子类构造器中默认有此方法)super()访问父类中的无参构造器,如果没有,要给super传递参数访问父类中的有参构造器②可以访问父类中与子类重名的属性或重写的方法,总之在重载和重写中要善于利用super和this。
应用:解释 源码中 a.equals(b)
1. Object类是所有类的父类,对于lang包中的方法,其子类中的属性可以随意调用,对于这些方法,传进去的参数可以用Object来接受。2. this关键字在方法内部指代的就是调用该方法的对象本身。
接下来仔细思考一个问题,为什么子类对象可以用父类类型进行接收?
原因:①父类引用虽然指向子类对象,但在调用方法时会根据实际对象类型执行相应的方法,这就是动态绑定。但父类引用只能访问父类中声明的方法和属性,如果子类重写了这些方法,则会调用子类的方法。而子类特有的方法则无法通过父类引用调用,除非进行向下转型。②- 子类是父类的一种特殊类型,它继承了父类的属性和方法,并且可能还添加了自己特有的属性和方法。因此,子类对象具有父类对象的所有特征,从逻辑上讲,子类对象可以被视为父类对象的一种扩展,所以可以将子类对象赋值给父类类型的变量。