B站 韩顺平 笔记 (Day 17)

发布于:2025-08-14 ⋅ 阅读:(13) ⋅ 点赞:(0)

目录

1(代码块)

1.1(注意事项与细节)

1.1.1(细节1)(重要背)

1.1.2(细节2)(超级重点)

1.1.3(细节3)

1.1.4(细节4)(难)

1.2(练习题)

1.2.1(题1)

1.2.2(题2)

2(单例模式)

2.1(什么是设计模式)

2.2(什么是单例模式)

2.3(饿汉式和懒汉式)

2.3.1(饿汉式代码解释)

2.3.2(懒汉式代码解释)

2.3.3(总结)

3(final关键字)

3.1(基本使用)

3.2(注意事项与细节)

3.2.1(细节1)

详解2):

详解3):

详解4):

详解5):

3.2.2(细节2)

详解7):

3.3(练习题)

3.3.1(题1)

3.3.2(题2)

4(抽象类)

4.1(抽象类的引入)

4.2(快速入门)

4.3(抽象类的介绍)

4.4(注意事项与使用细节)

4.4.1(细节1)

4.4.2(细节2)

4.4.3(细节3)(考点)

4.5(练习题)

4.6(抽象模板模式)

Template类

AA类

BB类

运行TestTemplate类

1(代码块)

1.1(注意事项与细节)

1.1.1(细节1)(重要背)

public class CodeBlockDetail01 {
    public static void main(String[] args) {

        //类被加载的情况举例:
        
        //(1) 创建对象实例时(new)
        AA aa1 = new AA(); //AA的静态代码快1被执行...
        
        //(2) 创建子类对象实例,父类也会被加载,而且父类先被加载,子类后加载
        AA aa2 = new AA(); //BB的静态代码快1被执行... \n AA的静态代码快1被执行...
        
        //(3) 使用类的静态成员时(静态属性,静态方法)
        System.out.println(Cat.n1); //Cat的静态代码快n1被执行... \n 999

        //static代码块是在类加载时执行的,而且只会被执行一次
        DD dd1 = new DD(); //DD的静态代码快1被执行... \n DD的普通代码快1被执行...
        DD dd2 = new DD(); //无                    \n DD的普通代码快1被执行...

        //普通的代码块,在创建对象实例时,会被隐式的调用。被创建一次,调一次。
        //如果只是使用类的静态成员时,普通代码块不会执行
        System.out.println(DD.n1); //DD的静态代码快1被执行... \n 8888
    }
}

class DD {
    public static int n1 = 8888;//静态属性

    //静态代码块
    static {
        System.out.println("DD的静态代码快1被执行...");
    }
    //普通代码块,在new对象时被调用,每创建一个就调一个
    //可以简单理解成:普通代码块是构造器的补充。(用到构造器时才会被调用)
    {
        System.out.println("DD的普通代码快1被执行...");
    }
}

class Animal {
    //静态代码块
    static {
        System.out.println("Animal的静态代码快1被执行...");
    }
}

class Cat extends Animal{
    public static int n1 = 999;//静态属性

    //静态代码块
    static {
        System.out.println("Cat的静态代码快n1被执行...");
    }
}

class BB {
    //静态代码块
    static {
        System.out.println("BB的静态代码快1被执行...");
    }
}

class AA extends BB{

    //静态代码块
    static {
        System.out.println("AA的静态代码快1被执行...");
    }
}

1.1.2(细节2)(超级重点)

public class CodeBlockDetail02 {
    public static void main(String[] args) {
        A a = new A();
        // (1) A 静态代码块01  (2) getN1被调用... (3)A 普通代码块01
        // (4) getN2被调用...  (5) A() 构造器被调用
    }
}

class A {
    { //普通代码块
        System.out.println("A 普通代码块01");
    }
    private int n2 = getN2();//普通属性的初始化


    static { //静态代码块
        System.out.println("A 静态代码块01");
    }

    //静态属性的初始化
    private static  int n1 = getN1();

    public static int getN1() {
        System.out.println("getN1被调用...");
        return 100;
    }
    public int getN2() { //普通方法/非静态方法
        System.out.println("getN2被调用...");
        return 200;
    }

    //无参构造器
    public A() {
        System.out.println("A() 构造器被调用");
    }

}

1.1.3(细节3)

public class CodeBlockDetail03 {
    public static void main(String[] args) {
        new BBB();
        //(1)AAA的普通代码块 (2)AAA()构造器 (3)BBB的普通代码块 (4)BBB()构造器
    }
}

class AAA { //父类Object
    {
        System.out.println("AAA的普通代码块");
    }
    public AAA() {
        //(1)super()
        //(2)调用本类的普通代码块
        System.out.println("AAA()构造器");
    }
}

class BBB extends AAA  {
    {
        System.out.println("BBB的普通代码块");
    }
    public BBB() {
        //(1)super()
        //(2)调用本类的普通代码块
        System.out.println("BBB()构造器");
    }
}

1.1.4(细节4)(难)

public class CodeBlockDetail04 {
    public static void main(String[] args) {
        //老师说明
        //(1) 进行类的加载
        //    1.1 先加载 父类 A02
        //    1.2 再加载 B02
        //(2) 创建对象
        //    2.1 从子类的构造器开始
        new B02();//对象
    }
}

class A02 { //父类
    private static int n1 = getVal01();
    
    static {
        System.out.println("A02的一个静态代码块..");//(2)
    }
    
    {
        System.out.println("A02的第一个普通代码块..");//(5)
    }
    public int n3 = getVal02();//普通属性的初始化
    
    public static int getVal01() {
        System.out.println("getVal01");//(1)
        return 10;
    }

    public int getVal02() {
        System.out.println("getVal02");//(6)
        return 10;
    }

    public A02() {//构造器
        //隐藏
        //super()
        //普通代码和普通属性的初始化......
        System.out.println("A02的构造器");//(7)
    }
}

class B02 extends A02 { //

    private static int n3 = getVal03();

    static {
        System.out.println("B02的一个静态代码块..");//(4)
    }

    public int n5 = getVal04();
    {
        System.out.println("B02的第一个普通代码块..");//(9)
    }

    public static int getVal03() {
        System.out.println("getVal03");//(3)
        return 10;
    }

    public int getVal04() {
        System.out.println("getVal04");//(8)
        return 10;
    }

    public B02() {//构造器
        //隐藏了
        //super()
        //普通代码块和普通属性的初始化...
        System.out.println("B02的构造器");//(10)
    }
}

静态 是跟类加载有关的

1.2(练习题)

1.2.1(题1)

先输出(1),再输出那俩100的行

注:调Person.total时会完成类的加载,所以会执行上面的static

1.2.2(题2)

注意:执行完static之后,不要急着执行Test构造器,因为还要执行普通属性和普通方法。所以去执行Sample sam1 = new Sample...

2(单例模式)

2.1(什么是设计模式)

2.2(什么是单例模式)

2.3(饿汉式和懒汉式)

2.3.1(饿汉式代码解释)

public class SingleTon01 {
    public static void main(String[] args) {
        //通过方法可以获取对象
        GirlFriend instance = GirlFriend.getInstance();
        System.out.println(instance);//GirlFriend{name='小红红'}

        GirlFriend instance2 = GirlFriend.getInstance();
        System.out.println(instance2);//GirlFriend{name='小红红'}

        System.out.println(instance == instance2);//T
    }
}

//有一个类, GirlFriend
//只能有一个
class GirlFriend {

    private String name;
    //public static  int n1 = 100;
    //为了能够在静态方法中,返回 gf对象,需要将其修饰为static
    private static GirlFriend gf = new GirlFriend("小红红");

    //如何保障我们只能创建一个 GirlFriend 对象
    //步骤[单例模式-饿汉式]
    //1. 将构造器私有化
    //2. 在类的内部直接创建对象(该对象是static)
    //3. 提供一个公共的static方法,返回 gf对象
    private GirlFriend(String name) {
        this.name = name;
    }
    
    public static GirlFriend getInstance() {
        return gf;
    }

    @Override
    public String toString() {
        return "GirlFriend{" +
                "name='" + name + '\'' +
                '}';
    }
}

2.3.2(懒汉式代码解释)

public class SingleTon02 {
    public static void main(String[] args) {
        System.out.println(Cat.n1); //若只有这一行代码,输出:999
        Cat instance = Cat.getInstance(); //加上这一行才会输出:构造器被调用
        System.out.println(instance); //Cat{name='小可爱'}

        //再次调用getInstance
        Cat instance2 = Cat.getInstance(); //无输出
        System.out.println(instance2); //Cat{name='小可爱'}
    }
}

//希望在程序运行过程中只能创建一个Cat对象
//使用单例模式
class Cat {
    private String name;
    public static int n1 = 999;
    private static Cat cat;//默认为null

    //步骤:
    //1.仍然将构造器私有化
    //2.定义一个static静态属性对象
    //3.提供一个公共public的static方法,可以返回一个Cat对象
    //4.懒汉式只有用户使用getInstance时,才返回cat对象,后面再次调用时则返回上次创建的cat对象
    //  从而保证了单例

    private Cat(String name) {
        System.out.println("构造器被调用");
        this.name = name;
    }
    public static Cat getInstance() {

        if(cat == null) {//如果还没有创建cat对象
            cat = new Cat("小可爱");
        }
        return cat;
    }

    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                '}';
    }
}

2.3.3(总结)

3(final关键字)

3.1(基本使用)

3.2(注意事项与细节)

3.2.1(细节1)

详解2):

详解3):

详解4):

详解5):

3.2.2(细节2)

详解7):

无final:导致BBB这个类被加载,所以静态代码块被执行

有final:

3.3(练习题)

3.3.1(题1)

public class FinalExercise01 {
    public static void main(String[] args) {
        Circle circle = new Circle(5.0);
        System.out.println("面积=" + circle.calArea());
    }
}

class Circle {
    private double radius;
    private final double PI;// = 3.14;
    //构造器
    public Circle(double radius) {
        this.radius = radius;
        //PI = 3.14;
    }
    {
        PI = 3.14;
    }

    public double calArea() {
        return PI * radius * radius;
    }
}

3.3.2(题2)

4(抽象类)

4.1(抽象类的引入)

public class Abstract01 {
    public static void main(String[] args) {
    }
}
abstract class Animal {
    private String name;
    public Animal(String name) {
        this.name = name;
    }
    //思考:这里eat 这里你实现了,其实没有什么意义
    //即: 父类方法不确定性的问题
    //===> 考虑将该方法设计为抽象(abstract)方法
    //===> 所谓抽象方法就是没有实现的方法
    //===> 所谓没有实现就是指,没有方法体
    //===> 当一个类中存在抽象方法时,需要将该类声明为abstract类
    //===> 一般来说,抽象类会被继承,有其子类来实现抽象方法.
//    public void eat() {
//        System.out.println("这是一个动物,但是不知道吃什么..");
//    }
    public abstract void eat()  ;
}

4.2(快速入门)

4.3(抽象类的介绍)

4.4(注意事项与使用细节)

4.4.1(细节1)

4.4.2(细节2)

详解7):

4.4.3(细节3)(考点)

4.5(练习题)

Employee类

abstract public class Employee {
    private String name;
    private int id;
    private double salary;

    public Employee(String name, int id, double salary) {
        this.name = name;
        this.id = id;
        this.salary = salary;
    }
    //将work做成一个抽象方法
    public abstract void work();

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
}

Manager类

public class Manager extends Employee {

    private double bonus;
    public Manager(String name, int id, double salary) {
        super(name, id, salary);
    }

    public double getBonus() {
        return bonus;
    }

    public void setBonus(double bonus) {
        this.bonus = bonus;
    }

    @Override
    public void work() {
        System.out.println("经理 " + getName() + " 工作中...");
    }
}

CommonEmployee类

public class CommonEmployee extends Employee{
    public CommonEmployee(String name, int id, double salary) {
        super(name, id, salary);
    }

    @Override
    public void work() {
        System.out.println("普通员工 " + getName() + " 工作中...");
    }
}

测试运行类

public class AbstractExercise01 {
    public static void main(String[] args) {
        //测试
        Manager jack = new Manager("jack", 999, 50000);
        jack.setBonus(8000);
        jack.work();

        CommonEmployee tom = new CommonEmployee("tom", 888, 20000);
        tom.work();
    }
}

4.6(抽象模板模式)

Template类

abstract public class Template { //抽象类-模板设计模式

    public abstract void job();//抽象方法

    public void calculateTime() {//实现方法,调用job方法
        //得到开始的时间
        long start = System.currentTimeMillis();
        job(); //动态绑定机制,从此出进入AA或BB
        //得的结束的时间
        long end = System.currentTimeMillis();
        System.out.println("任务执行时间 " + (end - start));
    }
}

AA类

//由Template的job()进入此方法的
public class AA extends Template {
    //计算任务
    //1+....+ 800000
    @Override
    public void job() { //实现Template的抽象方法job

        long num = 0;
        for (long i = 1; i <= 800000; i++) {
            num += i;
        }
    }
}

BB类

//由Template的job()进入此方法的
public class BB extends Template{

    public void job() {//这里也去,重写了Template的job方法

        long num = 0;
        for (long i = 1; i <= 80000; i++) {
            num *= i;
        }

    }
}

运行TestTemplate类

public class TestTemplate {
    public static void main(String[] args) {

        AA aa = new AA();
        aa.calculateTime(); //AA中没有此方法,所以找到父类calculateTime里面
        //这里还是需要有良好的OOP基础,对多态

        BB bb = new BB();
        bb.calculateTime();
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到