B站 韩顺平 笔记 (Day 17)
目录
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对象,需要将其修饰为staticprivate 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;}@Overridepublic String toString() {return "GirlFriend{" +"name='" + name + '\'' +'}';}
}
2.3.2(懒汉式代码解释)
public class SingleTon02 {public static void main(String[] args) {System.out.println(Cat.n1); //若只有这一行代码,输出:999Cat instance = Cat.getInstance(); //加上这一行才会输出:构造器被调用System.out.println(instance); //Cat{name='小可爱'}//再次调用getInstanceCat 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;}@Overridepublic 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;}@Overridepublic void work() {System.out.println("经理 " + getName() + " 工作中...");}
}
CommonEmployee类
public class CommonEmployee extends Employee{public CommonEmployee(String name, int id, double salary) {super(name, id, salary);}@Overridepublic 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@Overridepublic void job() { //实现Template的抽象方法joblong 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();}
}