Java SE 继承

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就能调用父类的属性与方法,体现出了继承的作用。
运行结果1
那么,如果子类中存在与父类相同的成员变量,在使用时,是使用子类中的还是父类中的呢?

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
我们可以总结:

在子类方法中 或者 通过子类对象访问成员时:
如果访问的成员变量子类中有,优先访问自己的成员变量;
如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错;
如果访问的成员变量与父类中成员变量同名,则优先访问自己的。

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进行调用。
运行结果3
可以看到,我们通过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();
    }
}

在父类和子类中分别添加构造方法。
运行结果4
可以看到,当调用子类的构造方法时,先调用父类的构造方法。

注意事项:

  1. 若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用基类构造方法
  2. 如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的父类构造方法调用,否则编译失败。
  3. 在子类构造方法中,super(…)调用父类构造时,必须是子类构造函数中第一条语句。
  4. super(…)只能在子类构造方法中出现一次,并且不能和this同时出现

4. 继承方式

在日常生活中,存在各种各样的类似与继承的关系,如
图例1
图例2
其中,Java并不支持多继承的关系。但是即使如此, 我们并不希望类之间的继承层次太复杂. 一般我们不希望出现超过三层的继承关系. 如果继承层次太多, 就需要考虑对代码进行重构了。

5. final关键字

final关键字的作用和C语言中的const类似。
当修饰变量或字段时,表示常量不能被修改。

final int a = 10;

当修饰类时,表示此类不能被继承

final public class Animal {
}

当修饰方法时,表示该方法不能被重写。

  • 12
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值