Java 继承

继承的格式:

在继承的关系中,"子类就是一个父类",也就是说,子类可以被当作父类看待
例如父类是员工,子类是讲师,那么"讲师就是一个员工" 关系:is-a

定义父类的格式(一个普通的类定义):
public class 父类名称{
    //...
}

定义子类的格式:
public class 子类名称 extends 父类名称{
    //...

 

继承中成员变量的访问特点:

父类:

public class Fu {
    int numFu = 10;
    int num = 100;

    public void methodFu() {
        // 使用的是本类当中的,不会向下找子类
        System.out.println(num);
    }
}

子类:

public class Zi extends Fu {
    int numZi = 20;
    int num = 200;

    public void methodZi() {
        // 因为本类当中有num,所以用的是本类当中的
        System.out.println(num);
    }
}

测试:

/*
在父子类的继承关系当中,如果成员变量重名,则子类对象有两种访问方式:

1. 直接通过子类对象访问成员变量:
    等号左边是谁,就优先用谁,没有则向上找
2. 间接通过成员方法访问成员变量
    该方法属于谁,则优先用谁的变量,没有再向上找
 */
public class Demo01ExtendsField {

    public static void main(String[] args) {
        Fu fu = new Fu(); // 创建父类对象
        System.out.println(fu.numFu); //只能使用父类东西,没有任何子类的内容

        Zi zi = new Zi();
        System.out.println(zi.numFu);
        System.out.println(zi.numZi);

        // 等号左边是谁,就优先用谁
        System.out.println(zi.num); // 优先子类,200

        // 这个方法是子类的,优先用子类的,没有再向上找
        zi.methodZi(); // 200

        // 这个方法是在父类中定义的,优先用父类的
        zi.methodFu();
    }
}

本类成员变量、父类成员变量和局部变量都重名情况下的处理:

/*
局部变量       直接写
子类成员变量    this.成员变量
父类成员变量    super.成员变量
 */
public class Demo01ExtendsField {

    public static void main(String[] args) {
        Zi zi = new Zi();

        zi.method();
    }
}
public class Fu {
    int num = 10;
}


public class Zi extends Fu {
    int num = 20;

    public void method() {
        int num = 30;
        System.out.println(num); // 30,局部变量
        System.out.println(this.num); // 20 本类成员变量
        System.out.println(super.num); // 10 父类成员变量
    }
}

继承中成员方法访问特点:

/*
在父子类的继承关系中,子类对象访问成员方法的规则:
    创建的对象是谁的(new 的是谁),就优先用谁的,没有则向上找

注意事项:
无论是成员方法还是成员变量,如果没有都是向上找父类,绝对不会向下找子类的
 */
public class Demo01ExtendsMethod {

    public static void main(String[] args) {
        Zi zi = new Zi();

        zi.methodFu();
        zi.methodZi();

        // new了子类对象,所以优先用了子类方法
        zi.method();
    }
}


public class Fu {
    public void methodFu() {
        System.out.println("父类方法执行");
    }

    public void method() {
        System.out.println("父类重名方法执行");
    }
}


public class Zi extends Fu {
    public void methodZi() {
        System.out.println("子类方法执行");
    }

    public void method() {
        System.out.println("子类重名方法执行");
    }
}

 重写:

重写(override)概念:在继承关系中,方法名称一样,参数列表也一样


重写(override):方法名称一样,参数列表也一样。也叫 覆盖、覆写
重载(overload):方法名称一样,参数列表不一样。

 

方法的覆盖重写特点:创建的是子类对象,则优先用子类方法

方法覆盖重写注意事项:

1. 必须保证父子类之间方法名相同,参数列表也相同

@Override:写在方法前面,用来检测是不是有效的正确覆盖重写。 也可以不写

2. 子类方法返回值必须小于等于父类方法返回值

3. 子类方法的权限必须大于等于父类方法的权限修饰符

父子类构造方法访问特点:

继承关系中,父子类构造方法的特点:
1. 子类必须调用父类构造方法,不写默认赠送super(), 写了则用写的
2. 子类构造方法可以通过super关键字调用父类重载构造
3. super 的父类重载构造调用,必须是子类构造方法第一个语句,所以一定是先调用父类构造,后执行子类构造 ; 不能一个子类构造调用多次super构造
4. 只有子类构造方法,才能调用父类构造方法 ;

super关键字三种用法:

1. 在子类成员方法中,访问父类成员变量
2. 在子类成员方法中,访问父类成员方法
3. 在子类构造方法中,访问父类构造方法

内存图展示: 

 

posted on 2021-06-22 16:00  mlllily  阅读(45)  评论(0编辑  收藏  举报