继承
继承的起源
在面向对象编程中,可以通过扩展一个已有的类,并继承该类的属性和行为,来创建一个新的类,这种方式称为继承(Inheritance)。
已有的类称为父类,而新类称为子类。父类也可以称为基类、超类,子类也可以称为派生类。
在面向对象编程中,当两个或多个类是不相同的,但是共享相同特征的时候,将共同的元素从类中拿出来,放到一个父类中。这些类继承父类,因此就继承了所有父类的特征,同时,每个子类中又保留了不同的特征。使用继承不仅可以重用已有的代码,从而避免代码重复,还可以创建一个更容易维护和修改代码的程序。
继承的优点:
- 代码的复用性
- 代码的扩展性
注:继承讲的是类和类的继承,不是对象和对象的继承
使用”is a”关系判断继承:
“is a”关系是一个简单而强大的规则,用于判断父类和子类的继承关系是否正确。当使用继承时,我们必须能够说子类“ is a(是一个)” 父类。如果这个语句是真的,那么继承关系就是对的。
Java中继承的实现
在Java中,一个类使用关键字extends继承其它类。关键字extends出现在类声明时的类名后,extends后面跟着的是要继承的类的名称。
public class Salary extends Employee //Salary类是Employee类的子类
子类的实例化
new关键字来实现。
注:并非是先创建一个父类对象,然后再创建一个子类对象。
而是只创建一个对象,先给父类的属性分配空间,然后再叠加子类的私有属性。
public class InheritDemo{
public static void main(String [] args){
System.out.println("实例化一个Employee对象");
Employee e = new Employee();
e.name = "张三";
e.address = "九眼桥一号洞";
单继承与多继承
某些OOP语言(例如C++)允许子类有多个父类。但是,在Java中这是不允许的。在Java中,一个类只能有一个父类。
多继承在Java中是不允许的。Java语言的目标之一是创建一个易于使用和理解的面向对象编程语言。而多继承只能给编程语言带来混淆。
一个Java类只能有一个父类。但是这并不意味着一个类没有祖父、曾祖父等等。一个Java类可以有父类、父类也可以父类,依此类推。
根类Object
Java语言API中包含了一个名为Object的特殊类,它是整个Java类层次中的根类。Object类在java.lang包中,是每个Java类的父类,要么是直接的父类,要么就是间接父类。
方法重写
子类可以重写从父类继承的方法,从而允许子类添加或者改变父类中方法的行为。这称为方法重写
当子类重写父类的方法时,必须遵循如下的规则:
- 子类的方法的返回值的类型、方法名和形式参数列表,必须和父类中的是相同的。如果子类中的方法与父类中的方法同名,但是子类的方法改变了形式参数列表,那么这是方法重载,而不是方法重写。不要混淆这两个概念,二者的用法是完全不同的。
- 访问修饰符必须不小于父类中的访问修饰符。例如,如果父类的方法是public,那么子类的必须是public。如果父类的方法是protected,那么子类必须是protected或public(public比protected访问权更大)。
- 子类中重写的异常不能抛出比父类更多的异常,其原因我们将在后面异常处理一章中讲解。
equals()方法
- “==”代表:如果两边的数据类型是基本数据类型,那么直接比较值是否相等;
- “equals”代表:默认情况下,调用的是
Object.equals()
,但是这个方法比较的是对象的引用是否一致,但是在某些特殊的业务场景中,我们也可以重写该方法。
super关键字
- super()代表父类的构造方法,这行代码必须放置在第一行,如果程序不显示写出,编译器也会默认添加上。
- super()代表父类的构造函数,这个默认的编译器会自动给我们添加子类构造的第一行
- this()代表本类中其他的构造函数。
this.属性或this.行为()(自己的)
-
this.
访问继承来自于父类的属性、行为 -
super.
代表的是继承于父类的那一部分的属性、行为,自己的不能访问 -
this.
的作用范围:可操作本类的所有属性,所有方法,还可以操作来自于继承父类的属性和行为 -
super.
的作用范围:只可以操作来自于继承父类的属性和方法。
final关键字
我们已经学习了创建符号常量时使用final关键字。符号常量在被赋值后就不能被改变。
现在我们已经学习了继承和方法重写,我们可以学习final关键字的另外两种用法了:
- final类。一个类可以声明为最终类的。最终类不能被有子类。
- final方法。一个方法可以声明为最终的。最终方法不能被重写。
final类
有时候,我们希望一个类成为最终类,不能被其它类继承,也就是不能有子类。在这种情况下,我们就需要在声明类时,在关键字class前加上关键字final,让该类成为一个最终类。
public final class Hourly extends Employee{
}
final方法
当子类重写父类的一个方法时,父类中被重写的方法实质上被隐藏了。在子类中,要调用父类中的方法,唯一的方法是显式地调用。如果我们编写的方法有中很重要的行为,我们不想子类重写,可以将该方法声明为最终方法。最终方法不能被子类重写。
Object类中的getClass()、wait()和notify()方法都是最终方法,这些方法不能被任何类重写。
当将方法声明为最终时,关键字final可以出现在返回值类型之前的任意位置,习惯上是放在访问修饰符之后。