目录
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();
}
}