继承
概念:
继承是面向对象最显著的一个特性。继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。
关键字: extends
特点:
-
继承意味着扩展,否则毫无意义,继承的意义就是为了代码的复用。要明确子类不是父类的子集这一概念
-
子类继承父类以后,父类中声明的属性、方法,子类就可以获取到
-
子类除了通过继承,获取父类的结构之外,还可以定义自己的特有的成分
-
Java中只有单继承,但是父类可以有多个子类
-
子类继承父类,继承了除构造函数的所有,因此,一旦发生继承,就要先利用super帮助父类构造父类本身。
这里注意:子类继承父类,不会继承父类的构造函数,是利用super 显示的调用父类的构造函数 -
访问顺序:
父类中的静态代码块 -》子类中的静态代码块 -》父类中的实例代码块 -》父类中的构造方法 -》子类中的实例代码块 -》 子类中的构造方法
-
protected——包的修饰访问限定修饰符
protected - 受保护的 -》主要体现在继承层次上
要体现封装性,想设成私有的private,但是设成私有的后派生出的子类就不能访问它。所以引入protected,只有继承了它的子类才能访问,别的不行 -
super和this的异同 -
super()和this()均需放在构造方法内第一行。
-
super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时如:super.变量名super.成员函数据名(实参)
-
this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名)
-
this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。
-
this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。
-
如果一个类被final所修饰,那么它就不能被继承了
多态
理解:
字面意思:一种事物多种形态
程序层次:有了面的向上转型, 动态绑定, 方法重写之后, 我们就可以使用 多态(polypeptide) 的形式来设计程序了.
-
向上转型:子类对象赋值给父类对象的过程叫做向上转型,但是父类的引用只能调用父类自己的方法或者访问自己的属性
向上转型发生的时机:
1)直接赋值 2)参数传递 3)方法返回 -
向下转型:父类对象通过强制类型转换赋值给子类的过程叫做向下转型。
但是,向下转型使用不出错的前提是 强制转换的类型必须是父类已经引用了子类(向下转型后的类型)的对象。不然会报类型转换错误。所以,在向下转型前要判断:
-
重写/覆盖/复写Override:
1)函数名相同
2)函数参数列表相同
3)返回值也要相同
4)静态的方法和 private 不能被重写
5)注意:子类的访问修饰限定符一定要大于等于父类的访问修饰限定符
6) 父类的方法不能是私有的?(因为在动态绑定阶段,如果父类的方法或属性是私有/static 的,那么不能通过编译,无法取得父类地址,所以不行)重载Overload:
1)函数名相同
2)参数列表不同(个数、类型)
3)返回值不做要求
重写和重载的区别:
-
运行时绑定 ( 动态绑定)的条件:
1)父类的引用 引用子类的对象
2)父类和子类都有同名的覆盖方法(重写) -
动态绑定的原理(了解)
子类没有重写eat方法时,调用的确实是父类自己的eat,重写后,编译时还在调用父类的eat方法,但是运行后确实子类的方法。在运行时,偷偷地改变了父类方法的地址,导致最终调用了子类方法的地址。
1)在编译的时候还是调用 Animal的eat()方法的地址,但是在运行时系统底层做了这样一个动作 篡改了Animal的eat()方法的地址
2)方法区:存放类的对象的信息注意: class对象存放在方法区(其他对象都在堆上)
3)反射 私有方法/属性 (private) 利用反射在类外也可以使用,甚至改掉
4)方法表和class类型不会随着new的增多而增加,他们是与类型相对应的方法表在编译时产生