引言
继承:面向对象的编程允许从已经存在的类中定义新的类。
面向过程重点在于方法的设计,面向对象将数据和方法结合在对象中。
父类和子类
如果C1扩展自另一个类C2,则
C1 称为次类、子类、扩展类、派生类
C2 称为超类、父类、基类
子类从父类继承数据域和方法,还可以添加新的数据域和方法
继承使用关键字 extends,例如 public class Rectangle extends GeometricObject
不是所有的"is-a"关系都用继承表达,但是继承表达出来的一定是"is-a"关系
Java不允许多重继承,即只能继承一个父类,这里与C\C++有所区别,但是接口可以多重继承
父类的构造方法不会被子类继承!
使用 super 关键字
关键字 super 指代父类,可以用于调用父类的方法,主要用于调用构造方法,例如:
super()
这是显式调用父类构造方法的唯一方式,括号里面可以加参数,若子类不写,则程序默认在构造方法第一行加super()
方法重写
方法重写:子类为了修改父类中的方法,在子类中定义一个和父类一样签名以及一样返回值类型的方法
注意:仅当父类方法可访问时,才能重写;
静态方法不能被覆盖,若被重写,则父类中的方法被隐藏,需要 父类名.静态方法名 调用隐藏方法。
为避免错误,使用Java特殊语法,重写标注,在重写方法前面放一个 @Override。比如父类toString方法被重写为tostring,这样写编译器不报错,但真正调用toString的时候调用的是父类的方法,属于程序员自己失误,加上 @Override 后,如果犯了上述错误,编译器会报错。
方法重写与重载
重写 是在子类中提供一个对方法的新的实现,具有相同签名和相同返回值,发生在子类中
重载 是使用同样名字但是不用签名来定义多个方法,具有相同名字,不相同的参数列表,可以在任意位置出现
多态
子类是父类的特殊化,每个子类的实例都是其父类的实例,但是反过来就不对。
例如:每个圆都是一个几何对象,并非每个几何对象都是圆。
因此,总是可以将子类的实例传给需要父类型的参数。
例如:void function(Object o) 中,可以传进任意引用。
简单来说,多态 父类型的引用可以引用子类型的对象。
动态绑定
Object o = new Wangdandan();
声明类型:一个变量被声明的某种类型,o的声明类型是Object
实际类型:变量引用的实际类,o的实际类型是Wangdandan
如果Wangdandan中重写了toString方法的话,o调用哪个toString方法由实际类型决定,这就叫做动态绑定
JVM决定运行时调用哪个方法。
对象转换和 instanceof 运算符
对象转换:对象的引用可以类型转换为对另一种对象的引用
上面例子中,o转换成Wangdandan对象,被称为隐式转换
如果 Wangdandan w = o;
将会发生编译错误,因为编译器不确定o是不是Wangdandan的对象,所以报错,为了告诉编译器这句话是对的,可以显式转换:
Wangdandan w = (Wangdandan)o;
向上转换可以随便写,但是向下转换必须要显式地写出来。
但是不一定每次都能转换成功,为了确保该对象是另一个对象的实例,可以使用 instanceof 运算符:
if(o instanceof Wangdandan)
Wangdandan w = (Wangdandan)o;
一个好的经验是把变量定义为父类型,这样就可以接收任何子类型的值。
还要注意成员访问运算符(.)的优先级高于类型转换运算符,所以得多加个括号。
防止扩展和重写- final
一个被 final 修饰的类和方法都不能被扩展,被其修饰的数据域是一个常数。
final 标明该类是最终的,是不能作为父类的,比如 Math 类