CGB2105-Day07--笔记

1 继承

1.1 概述

在现实生活中,说到继承,多会想到子女继承父辈的财产、事业等。在程序中,继承描述的是事物之间的所属关系,通过继承可以使多种事物之间形成一种关联体系。
在Java中,类的继承是指在一个现有类的基础上去构建一个新的类,构建出来的新类被称作子类现有类被称作父类或基类,子类会自动拥有父类所有可继承的属性和方法。

1.2 特点

  1. 使用extends关键字来表示继承关系
  2. 相当于子类把父类的功能复制了一份
  3. Java只支持单继承
  4. 继承可以传递(爷爷/儿子/孙子这样的关系)
  5. 父类的私有成员也会被继承,但由于私有限制访问,所以子类不能使用父类的私有资源
  6. 继承多用于功能的修改,子类可以在拥有父类功能的同时,进行功能拓展
  7. 像是is a的关系

1.2.1 继承案例练习

public class ExtendsDemo {
    public static void main(String[] args) {
        Animal a = new Animal();
        Cat c = new Cat();
        MiaoMiao m = new MiaoMiao();
        // 利用对象调用方法
        a.eat();
        c.eat();
        m.eat();
        /**
         * 3、继承还具有传递性,爷爷的功能会传给爸爸,爸爸的功能会传给儿子
         */
    }
}

/**
 * 1、我们通过extends关键字建立子类与父类的继承关系
 * 格式:子类 extends 父类
 * 2、java只支持单继承,一个字类只能有一个父类,但是一个父类可以有多个子类
 */

// 创建爷爷类

/**
 * 6、继承是is a的关系,比如:小猫是小动物,MiaoMiao是一只小猫
 * 继承要求子类必须是父类的一种下属类型,依赖性非常强,强耦合
  */
class Animal {
    public void eat() {
        System.out.println("小动物Animal吃啥都行~");
    }
}

// 创建爸爸类,并与Animal类建立继承关系
class Cat extends Animal {
    int a = 10;
    private int b = 100;
}

// 创建孙子类,并与Cat类建立继承关系
class MiaoMiao extends Cat {
    /**
     * 4、子类可以拥有自己独有的方法,实现了功能的拓展,青出于蓝而胜于蓝
     */
    public void studyjava() {
        System.out.println("这是一只会编程的猫");
        /** 5、子类继承父类以后,可以使用父类所有非私有资源
         * 注意:这个私有资源是由于子类不可见而不能使用的,不是因为没有继承
         * 因为子类在继承了父类以后,相当于把父类的功能完全赋值了一份
         */
        System.out.println(a);
        //System.out.println(b);
    }
}

2 super关键字

我们可以把super看作是父类的对象:Father super = new Father();

  1. 当父类的成员变量与子类的变量同名时,使用super指定父类的成员变量
  2. 使用super在子类构造方法的第一行调用父类构造方法的功能
    super();–调用的是父类的无参构造
    super(参数);–调用的是父类对应参数的构造方法
    注意:在构造方法里,出现的调用位置必须是第一行

2.2 继承的用法

2.2.1 练习:super之继承中成员变量使用

/**
 * 本类用于测试继承中成员变量的使用
 */
public class TestExtends1 {
    public static void main(String[] args) {
        Father f = new Father();
        Son s = new Son();
        s.eat();
    }
}

// 创建父类
class Father {
    int count = 1;
    int sum = 2;
}
// 创建子类
class Son extends Father {
    int sum = 100;
    public void eat() {
        int sum = 10;
        System.out.println(sum);// 打印局部变量sum
        System.out.println(this.sum); // 打印成变量sum

        /**
         * 在子类中使用父类的sum资源,需要使用super进行指定
         * super表示父类的对象,可以理解成Father super = new Father();
         */
        System.out.println(count);
        System.out.println(super.sum);// 使用父类重名的成员变量
    }
}

2.2.2 super之继承中构造方法的使用

/**
 * 1、子类创建对象时,默认会先去调用父类的构造方法
 * 2、原因是由于子类构造函数第一行默认存在super()--表示调用父类的无参构造
 * 3、当父类没有无参构造时,可以通过super(参数)调用父类的其他含参构造
 * 4、构造方法不可以被继承,因为语法的原因,构造方法要求与类名同名,所以不符合要求
 */
public class TestExtends2 {
    public static void main(String[] args) {
        Father2 f2 = new Father2("红烧肉");
        Son2 s2 = new Son2();
    }
}

class Father2 {
//    public Father2() {
//        System.out.println("我是Father2无参构造");
//    }

    public Father2(String s) {
        System.out.println("爸爸爱吃" + s);
    }
}

class Son2 extends Father2 {
    public Son2() {
        super("狮子头");
        System.out.println("我是Son2的无参构造");
    }
}

3 方法重写Override

  1. 继承以后,子类就拥有了父类的功能
  2. 在子类中,可以添加子类特有的功能,也可以修改父类的原有功能
  3. 子类中方法的签名与父类完全一样时,会发生覆盖/复写的现象
  4. 注意: 父类的私有方法不能被重写
  5. 重写的要求:两同两小一大
    两同:方法名 参数列表 要完全一致
    两小:
    子类返回值类型小于等于父类的返回值类型(注意此处说的是继承关系,不是值大小)
    子类抛出异常小于等于父类方法抛出异常
    一大:子类方法的修饰符权限要大于等于父类被重写方法的修饰符权限

3.1 练习:继承中成员方法的使用

/**
 * 方法的重写:继承后子类对父类的功能不满意,就可以重写父类的功能
 * 重写的语法规则:两同,两小,一大
 * 一大:子类方法的修饰符范围 >= 父类方法的修饰符范围--这里指的是访问控制符
 * 两同:方法名相同,参数列表相同
 * 两小:子类方法的返回值类型 <= 父类方法的返回值类型
 *      子类方法抛出的异常类型 <= 父类方法抛出的异常类型
 * 注意:1、如果父类方法的返回值类型是void,子类保持一致即可
 *      2、子类不可以重写父类的私有方法,还是因为不可见
 */
public class TestExtends3 {
    public static void main(String[] args) {
        Father3 f3 = new Father3();
        Son3 s3 = new Son3();
        f3.eat();
        /**
         * 1、继承后,子类可以使用父类的非私有资源
         */
        s3.eat();
        /**
         * 3、如果子类对父类的功能进行重写,调用的是重写后的功能
         */
    }
}

class Father3 {
    public void eat() {
        System.out.println("爸爸爱吃肉");
    }

    public void play() {
        System.out.println("吕布爱貂蝉");
    }
}

class Son3 extends Father3 {
    public void studyJava() {
        System.out.println("拓展学习Java的功能");
    }

    /** 4、@Override:这是一个注解,可以理解成一个标签,标记这个方法是一个重写的方法 */
    @Override
    public void eat() {
        System.out.println("儿子爱吃蔬菜");
    }
}

4 static关键字

4.1 概念

是java中的一个关键字
用于修饰成员(成员变量和成员方法)

4.2 特点

  1. static可以修饰成员变量和方法
  2. 被static修饰的资源称为静态资源
  3. 静态资源随着类的加载而加载,最先加载,优先于对象进行加载
  4. 静态资源可以通过类名直接调用,也被称作类资源
  5. 静态被全局所有对象共享,值只有一份
  6. 静态资源只能调用静态资源
  7. 静态区域内不允许使用this与super关键字

4.2.1 static关键字入门案例练习

public class TestStatic1 {
    public static void main(String[] args) {
        /**
         * 3、静态资源可以通过类名直接调用
         * 原因,静态资源优先于对象进行加载,它是随着类的加载而加载的
         * 比对象先加载进入内存,所以没对象时也可以通过类名直接调用
         */
        System.out.println(Student.name);
        Student.study();
        Student s = new Student();
        System.out.println(s.sno);
        System.out.println(s.name);
        s.study();
        s.name = "鹌鹑蛋罐头";
        System.out.println(s.name);
        System.out.println(Student.name);
        /**
         * 4、静态资源被全局所有对象共享
         */
        Student s2 = new Student();
        System.out.println(s2.name);
        System.out.println(Student.name);
        s2.name = "牛肉罐头";
        System.out.println(s.name);
        System.out.println(s2.name);
        System.out.println(Student.name);
    }
}

class Student {
    /**
     * 1、可以通过static关键字来修饰成员变量与方法,修饰方法一般写在权限修饰符之后
     * 2、被static修饰的资源称作静态资源
     */
    int sno;
    static String name;

    public static void study() {
        System.out.println("别闹?学Java呢~");
    }

    public void speak() {
        System.out.println("会要大声说出来");
    }
}

4.2.2 static静态调用关系

/**
 * 总结:
 *      1、普通资源既可以调用普通资源,也可以调用静态资源
 *      2、静态资源只能调用静态资源
 */
public class TeatStatic2 {
}

class Teacher {
    String name;
    public void teach() {
        System.out.println("正在授课ing....");
        /**
         * 1、普通资源能否调用静态资源?----可以
         */
        System.out.println(age);
        ready();
    }

    static int age;
    public static void ready() {
        System.out.println("正在备课ing...");
        /**
         * 2、静态资源调用普通资源
         */
        //System.out.println(name);
        //teach();
    }

    public static void eat() {
        System.out.println("正在吃饭中ing...");
        /**
         * 3、静态资源能否调用静态资源
         */
        System.out.println(age);
        ready();
    }
}

5 静态代码块、构造代码块、局部代码块

5.1 静态代码块格式

在这里插入图片描述
静态资源随着类的加载而加载,并且只被加载一次,一般用于项目的初始化
特点: 被static修饰,位置在类里方法外

5.2 三种代码块的比较

  1. 静态代码块:在类加载时就加载,并且只被加载一次,一般用于项目的初始化
  2. 构造代码块:在创建对象时会自动调用,每次创建对象都会被调用,提取构造共性
  3. 局部代码块:方法里的代码块,限制局部变量的范围

5.2.3 静、构、局代码块练习

/**
 * 总结:
 *  执行顺序:
 *      静态代码块——>构造代码块——>构造方法【对象创建成功】——>局部代码块
 */
public class TestStaticBlock {
    // 6、创建对象
    public static void main(String[] args) {
        Person p = new Person();
        // 7、触发局部代码块
        p.play();
    }
}

// 1、创建Person类
class Person {
    // 8、创建静态代码块
    /**
     * 位置:类里方法外
     * 执行时机:静态代码块也属于静态资源,随着类的加载而加载,优先于对象加载,而且静态资源只会加载一次
     * 作用:用于加载哪些第一时间就加载,并且只加载一次的资源
     */
    static {
        System.out.println("我是静态代码块");
    }
    // 2、创建构造代码块
    /**
     * 位置:类里方法外
     * 执行时机:每次创建对象时被触发,并且优先于构造方法执行
     * 作用:用于提取所有构造方法的共性功能
     */
    {
        System.out.println("我是构造代码块");
    }

    // 5、创建构造方法
    public Person() {
        System.out.println("我是无参构造");
    }

    // 3、创建普通方法
    public void play() {
        System.out.println("我是一个普通方法");
        // 4、创建局部代码块
        /**
         * 位置:方法里
         * 执行时机:执行本局部代码块在的方法是才会执行
         * 作用:用于限制变量的作用范围
         */
        {
            System.out.println("我是局部代码块");
        }
    }
}

总结:
执行顺序:静态代码块——>构造代码块——>构造方法【对象创建成功】——>局部代码块

6 final关键字

6.1 概述

  1. 是java提供的一个关键字
  2. final是最终的意思
  3. final可以修饰类,方法,字段(属性)
    初衷:java出现继承后,子类可以更改父类的功能,当父类功能不许子类改变时,可以利用final关键字修饰父类。

6.2 特点

  1. 被final修饰的类,不能被继承
  2. 被final修饰的方法,不能被重写
  3. 被final修饰的字段是个常量,值不能被修改
  4. 常量的定义形式:final 数据类型 常量名 = 值

6.2.1 final入门案例

public class TestFinal {
    public static void main(String[] args) {
        Son s = new Son();
        //s.name = "干饭人"; // 会报错,因为常量的值不能被修改
    }
}

/**
 * 1、final表示最终,可以用来修饰类
 * 但是被final修饰类是最终类,无法被继承
 * 也就是没有子类,他自己就是叶子节点
 */
//final class Father {
class Father {
    // 定义父类的普通方法

    /**
     * 2、final可以用来修饰方法,被final修饰的方法是这个方法的最终实现,不可以被重写
     */
//    final public void work() {
//        System.out.println("在车间上班");
//    }

    public void work() {
        System.out.println("在车间上班");
    }
}

class Son extends Father {
    /**
     * final可以用来修饰“变量”,注意其实不是“变量”,而是常量
     * 常量的值是不可以被更改的
     * 定义常量时必须给常量同时赋值,不能先定义在赋值,不符合语法
     */
    final String name = "打工人";
    final int a = 0;
    @Override
    public void work() {
        System.out.println("在格子间上班");
    }
}

7 拓展

7.1 his与super的区别

this代表的是本类对象的引用,我们可以把this看作是Cat this = new Cat();
super代表的是父类对象的引用,我们可以把super看作是Father super = new Father();
当本类的成员变量与局部变量同名时,需要使用this.变量名指定本类的成员变量
当本类的成员变量与父类的成员变量同名时,需要使用super.变量名指定父类的成员变量
this可以实现调用本类构造方法的功能,不能互相调用,需要写在构造方法首行
this();表示调用本类的无参构造 this(参数);表示调用本类的对应参数的构造
super也可以实现调用父类构造方法的功能
super();表示调用父类的无参构造 super(参数);表示调用父类的对应参数的构造
注意:super的使用前提是继承,没有父子类关系,就没有super
注意:this调用构造方法或者super调用构造方法,都必须出现在构造方法的第一行
注意:如果父类没有无参构造,需要手动在子类构造方法的第一行调用其他的含参构造
拓展:如果子类重写了父类的方法以后,可以使用super.方法名(参数列表)来调用

7.2 重载Overload 与重写Override的区别

重载:在一个类中的现象:同一个类中,存在方法名相同,参数列表不同的方法
重写:是指建立了继承关系以后,子类对父类的方法不满意,可以重写,遵循两同两小一大原则
重载的意义:是为了外界调用方法时方便,不管传入什么样的参数,都可以匹配到对应的同名方法
重写的意义:在不修改源码的情况下,进行功能的修改与拓展(OCP原则:面向修改关闭,面向拓展开放)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

直男编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值