1. 继承的定义
修饰符 class 子类 extends 父类 {
// ...
}
继承是Java面向对象的三大特征之一,可以使子类拥有父类所具有的属性与方法。
从上述代码可以看到,通过使用extends关键字,可以达到继承的效果。
例如:
public class Parent {
public String name="小王";
public int age=20;
public void func1(){
System.out.println("父类方法被调用");
}
}
public class Child extends Parent{
public void func2(){
System.out.println("子类方法被调用");
}
}
public class TestExtends {
public static void main(String[] args) {
Child test1 = new Child();
System.out.println(test1.name);
System.out.println(test1.age);
test1.func1();
test1.func2();
}
}
从代码中可以看出,子类Child继承了父类Parent的成员变量name和age以及成员方法func1,并且在测试类中,通过子类创建的实例对象test1就能调用父类的属性与方法,体现出了继承的作用。
那么,如果子类中存在与父类相同的成员变量,在使用时,是使用子类中的还是父类中的呢?
public class Base {
public int a = 10;
public int b = 20;
}
public class Derived extends Base{
int a = 100;
double b =1;
public static void main(String[] args) {
Derived test1 = new Derived();
System.out.println(test1.a);
System.out.println(test1.b);
}
}
在父类Base中存在整型a和b,在子类Derived中存在整型a,和双浮点b。
我们可以总结:
在子类方法中 或者 通过子类对象访问成员时:
如果访问的成员变量子类中有,优先访问自己的成员变量;
如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错;
如果访问的成员变量与父类中成员变量同名,则优先访问自己的。
2. super关键字
如果存在上述情况(子类和父类有相同名称的成员),但还想在子类方法中去访问父类的同名成员,怎么办?
这时候就应该使用super关键字。
public class Base {
public int a = 10;
public int b = 20;
public void func1(){
System.out.println("父类中的方法");
}
}
public class Derived extends Base {
int a = 100;
double b = 1;
public void func1(){
System.out.println("子类中的方法");
}
public void func2(){
System.out.println(super.a);
System.out.println(super.b);
System.out.println(this.a);
System.out.println(this.b);
super.func1();
this.func1();
}
public static void main(String[] args) {
Derived test2 = new Derived();
test2.func2();
}
}
我们分别用super和this进行调用。
可以看到,我们通过super关键字成功调用了父类中的同名成员和方法。
需要注意的是,super只能在非静态方法中使用。
3. 子类构造方法
当子类构造对象时,需要先调用父类的构造方法,才能执行子类的构造方法。
例如:
public class Base {
public Base(){
System.out.println("父类的构造方法");
}
}
public class Derived extends Base{
public Derived(){
System.out.println("子类的构造方法");
}
public static void main(String[] args) {
Derived test3 = new Derived();
}
}
在父类和子类中分别添加构造方法。
可以看到,当调用子类的构造方法时,先调用父类的构造方法。
注意事项:
- 若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用基类构造方法
- 如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的父类构造方法调用,否则编译失败。
- 在子类构造方法中,super(…)调用父类构造时,必须是子类构造函数中第一条语句。
- super(…)只能在子类构造方法中出现一次,并且不能和this同时出现
4. 继承方式
在日常生活中,存在各种各样的类似与继承的关系,如
其中,Java并不支持多继承的关系。但是即使如此, 我们并不希望类之间的继承层次太复杂. 一般我们不希望出现超过三层的继承关系. 如果继承层次太多, 就需要考虑对代码进行重构了。
5. final关键字
final关键字的作用和C语言中的const类似。
当修饰变量或字段时,表示常量不能被修改。
final int a = 10;
当修饰类时,表示此类不能被继承
final public class Animal {
}
当修饰方法时,表示该方法不能被重写。