继承是Java中实现代码重用的重要手段之一。Java只支持单继承,即一个类只能有一个直接父类。java.lang.Object类是所有Java类的祖先。
is-a来判断是否使用继承 继承是代码复用的一种方式。
语法
修饰符 子类 extends[关键字] 父类{代码块}
继承通过关键字extends关键字实现,其中子类,父类[基类、超类]。
修饰符如果是public则该类在整个项目都可见;若无public修饰符,则该类只在当前包可见,不可使用private和protected修饰。
子类可从父类继承的“财产”
- 继承public和protected修饰的属性和方法,无论子类和父类是否在同一个包里。
- 继承默认权限修饰符的属和方法,但子类和父类必须在同个包里。
- 无法继承private修饰的属性和方法。
- 无法继承父类的构造方法。
子类构造方法调用父类会默认调用,删除后会隐式调用。
重写和继承关系中的构造方法
在子类中可以根据需求对从父类继承的方法进行重新编写,称为方法的重写或方法的覆盖(overriding)。
方法重写必须满足的要求
- 重写方法和被重写方法必须具有相同的方法名。
- 重写方法和被重写方法必须具有相同的参数列表。
- 重写方法的返回值类型必须和被重写方法的返回值类型相同或是其子类。
- 重写方法不能缩小被重写方法的访问权限。
重载和重写的区别?
重载涉及同一个类中的同名方法,要求方法名相同,参数列表不同,与返回值类型、访问修饰符无关。
重写涉及的是子类和父类之间的同名方法,要求方法名相同,参数列表相同,返回值类型相同(或是其子类)。访问修饰符不能严于父类。
Super
子类中想调用父类的被重写的方法,可以在子类方法中通过“super.方法名”来实现。
super代表对当前对象的直接父类对象的默认引用。
super必须出现在子类(子类的方法和构造方法)中,而不是其他位置。
可以访问父类的成员,如父类的属性、方法、构造方法。
注意访问权限的限制,如无法通过super访问private成员。
super.父类属性 //访问直接父类的属性
super.方法() //访问直接父类的方法
super(有参或无参) //访问直接在构造方法中只能在第一行
this与super在构造方法中调用构造方法时不能兼容。其余情况可以兼容。
继承条件下构造方法的调用规则
- 如果子类的构造方法中没有通过super显示调用父类的构造方法。也没用通过this显式调用自身的其他构造方法,则会默认先调用父类无参构造方法,在这种情况下有无“super()”,效果相同
- 如过子类的构造方法中通过super显式调用父类的有参构造方法,则讲执行父类相应的构造方法,而不执行无参构造。
- 如果子类的构造方法中通过this显式调用自身的其他构造方法,则在相应构造方法中应用以上两条规则
- 特别注意:如果存在多级继承关系,则在创建一个子类对象时,以上规则会多次向更高一级父类应用,一直到执行顶级父类Object类的无参构造方法为止。
- 在构造方法中如果有this和super则只能是第一条语句。
- 在一个构造方法中不允许同时出现使用this和super语句调用构造方法(否则就有两条第一条语句)。
- 在类方法中不允许出现this和super关键字。
- 在实例方法中this和super不要求是第一条语句,可以共存。
抽象类
抽象类和抽象方法的特点:
- 抽象类和抽象方法都通过abstract关键字来修饰。
- 抽象类不能实例化,抽象类中可以没有、有一个或多个抽象方法,甚至全部方法都可以是抽象方法
- 抽象方法只有方法声明,没有方法实现。有抽象方法的类必须声明为抽象。非抽象类若继承抽象类,则必须重写父类的所有抽象方法,子类必须重写所有的抽象方法才能实例化,否则子类还是一个抽象类。
- abstract可以用来修饰类和方法,但不能用来修饰属性和构造方法。
抽象类中可以有构造方法吗?
抽象类可以有构造方法,其构造方法可以被本类的其他构造方法调用,若此构造方法不是由private修饰,也可以被本类的子类中的构造方法调用。
final修饰符
- 用final修饰的类,不能再被继承。
- 用final修饰的方法不能被子类重写。
- 用final修饰的变量(包括成员变量和局部变量)将变成常量,只能赋值一次。
final与abstract的区别:
- final和abstract是功能相反的两个关键字。
- abstract可以用来修饰类和方法,不能用来修饰属性和构造方法。final可以用来修饰类、方法和属性,不能修饰构造方法。
- Java提供的很多类都是final类,例如String类,Math类,它们不能再有子类。Object类中一些方法,如getClass()、notify()、wait()都是final方法,只能被子类继承而不能被重写。但是hashCode()、toString()、equals(Object obj)不是final方法,可以被重写。
使用final修饰引用型变量时,变量的值是固定不变的,而变量所指向的对象的属性值是可变的。
abstract不能和private同时修饰一个方法。
abstract不能和static同时修饰一个方法。
abstract不能和final同时修饰一个方法或类。