Java——继承(二)

一、super关键字


Super关键字的作用:在子类方法中访问父类的成员。

//Father.java
public class Father {
    int a = 20;
    int b = 30;
    public void method1(){
        System.out.println("Father.method1");
    }
}
//Son.java
public class Son extends Father{
    int a = 10;
    char b = 'b';
    //同名,相同参数列表
    public void method1(){
        System.out.println("Son.method1");
    }

    public void method2(){
        //直接访问只能访问到子类的成员变量
        System.out.println("a = " + a);
        System.out.println("b = " + b);
        //使用super访问到父类中的成员变量
        System.out.println("super.a = " + super.a);
        System.out.println("super.b = " + super.b);
        method1(); //直接访问只能访问到子类
        super.method1(); //使用super关键字进行访问
    }
    public static void main(String[] args) {
        Son son = new Son();
        son.method2();
    }
}

在这里插入图片描述

super和this的异同

相同:

  • 都是java的关键字
  • 都只能在非静态方法中使用,用来访问非静态成员方法和字段。
  • 都在构造方法中调用,都必须是构造方法的第一条语句(不能同时存在

不同:

  • this是当前对象的引用,super是父类对象的引用。
  • 非静态成员方法中,this是用来访问本类的方法和属性,super用来访问父类继承下来的方法和属性。
  • this是非静态成员方法的一个隐藏参数,super不是隐藏参数。
  • 成员方法访问成员时,编译过后会将this还原,通过this来进行访问。使用super访问父类成员,编译之后在字节码层面是不存在super的。
    在这里插入图片描述
    在这里插入图片描述
  • 在构造方法中,this调用本类构造方法,super用于调用父类构造方法,两种不能同时存在。
  • 构造方法中一定会存在super调用,编译器会自动增加,但this没写则没有。

二、protected关键字


范围privatedefaultprotectedpublic
同一个包中的同一个类可以访问可以访问可以访问可以访问
同一个包中的不同类可以访问可以访问可以访问
不同包中的子类可以访问可以访问
不同包中的非子类可以访问

包的结构,通过下面的例子来介绍protected关键字:
在这里插入图片描述

public class A {
    private int a;
    protected int b;
    public int c;
    int d;
}

//在相同包的子类中
public class AA extends A{
    public void method(){
        //super.a = 10; // 父类的private成员不可见
        super.b = 20; // 父类的protected成员可以访问
        super.c = 30; // 父类中public成员可以访问
        super.d = 40; // 父类default成员可以访问
    }
}
//不同包的子类
public class B extends A {
    public void method(){
        //super.a = 10; //父类的private成员不可见
        super.b = 20; //父类protected成员可以访问
        super.c = 30; //父类public成员可以访问
        //super.d = 40; //父类default成员不能直接
    }
}
//不同包中的类
public class TestB {
    public static void main(String[] args) {
        B b = new B();
        b.method();
        //System.out.println(b.a); //父类的private成员不可见
        //System.out.println(b.b); //父类的protected成员不能直接访问
        System.out.println(b.c); //父类public成员可以访问
        //System.out.println(b.d); //父类的default成员不可直接访问
    }
}

三、final关键字


final关键字可以用来修饰变量、成员方法和类。

1、修饰变量或字段,表示常量。

final int a = 10;
a = 20; // 常量不能被修改

2、修饰类,表示该类不能被继承。

final public class A {
}
public class B extends A {
    public static void main(String[] args) {
    }
}

在这里插入图片描述

3、修饰方法,表示方法不能被重写

public class A {
    public final void method(){
        System.out.println("A.method");
    }
}
public class B extends A {
    public void method(){    } //会报错
    public static void main(String[] args) {
    }
}

在这里插入图片描述

四、初始化(代码块执行顺序)


在没有继承关系时的执行顺序:

class Animal {
    public String breed; //品种
    public String name; //名字

    public Animal(String breed, String name) {
        this.breed = breed;
        this.name = name;
        System.out.println("构造方法");
    }
    {
        System.out.println("实例代码块"); //有类的创建才会执行实例代码块
    }
    static {
        System.out.println("静态代码块"); //只在类加载阶段执行一次,只执行一次
    }
}
public class Test {
    public static void main(String[] args) {
        Animal animal = new Animal("雪纳瑞","小白");
    }
}

在这里插入图片描述
当有继承关系时的执行顺序:

class Animal{
    public String breed; //品种
    public String name; //名字

    public Animal(String breed, String name) {
        this.breed = breed;
        this.name = name;
        System.out.println("父类构造方法");
    }
    {
        System.out.println("父类实例代码块");
    }
    static {
        System.out.println("父类静态代码块");
    }
}

class Dog extends Animal{
    public Dog(String breed,String name){
        super(breed, name);
        System.out.println("子类的构造方法");
    }
    {
        System.out.println("子类的实例代码块");
    }
    static {
        System.out.println("子类静态代码块");
    }
}

public class Test {
    public static void main(String[] args) {
        Animal animal = new Animal("美洲豹","旺财"); //实例化父类
        System.out.println("<<<<<<<<<<<<<<<<我是分隔线>>>>>>>>>>>>>>>");
        Dog dog = new Dog("拉布拉多","金毛"); //实例化子类
    }
}

在这里插入图片描述
结论:

  • 静态代码块都只执行一次
  • 父类静态代码块最早执行,且优先于子类静态代码块执行
  • 父类实例代码块和父类构造方法紧接着执行
  • 子类的实例代码块和子类构造方法紧接着再执行
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值