单例设计模式(思想)
1.单例设计模式的概念: 单实例(单对象)
核心: 在程序运行时,无论怎么创建对象
该对象 有且仅有一个存在
2.单例设计模式的思路?
1️⃣对象不能让用户创建(不能在本类以外创建)---->私有化构造方法
2️⃣对象应该在类的内部创建(私有化 因为下面静态方法要调用)
3️⃣开放一个让用户在类外面 调用对象的方法(静态方法,因为成员方法要创建对象才能调用)
3.单例设计模式的分类
1️⃣饿汉式单例:不管你调不调用这个对象的开放方法,都会先将对象创建出来
2️⃣懒汉式单例:只有你第一次调用这个对象的开放方法,这个对象才会被创建出来.
// 1.饿汉式单例设计模式 举例
class SingleE{
// 2.自己创建对象(私有的静态变量,因为被静态方法调用)
private static SingleE singleE = new SingleE();
// 1.构造方法私有化(外界不能创建对象)
private SingleE() {
}
// 3.开放一个方法 能让外界拿到对象
// 外界不可能 创建出对象来调用这个方法
// 所以使用静态方法
public static SingleE getInstance() {
return singleE;
}
}
// 2.懒汉式单例设计模式 举例
// 不完整的懒汉式单例(出现线程问题)
class SingleL{
// 2.声明一个本类对象的引用( 与饿汉式单例不同的地方 )
private static SingleL singleL = null;
// 1.私有化构造方法
private SingleL() {
}
// 3.开放访问方法
public static SingleL getInstance() {
// 判断
if (singleL == null) {
singleL = new SingleL();
}
return singleL;
}
}
// 调用这两种单例设计模式
public class Demo03 {
public static void main(String[] args) {
// 获取单例对象
SingleE s1 = SingleE.getInstance();
SingleE s2 = SingleE.getInstance();
System.out.println(s1);
System.out.println(s2);
}
}
模板设计模式(思想)
前提: 抽象[通过多态创建对象]
1.抽象的概念: 不知道怎么具体描述该事物
关键词 abstract
abstract 修饰类 抽象类
修饰方法 抽象方法
2.抽象的注意事项:
1️⃣抽象方法没有实现部分 (因为没有具体描述,所以不能实现)
2️⃣抽象方法必须在抽象类中才能声明
3️⃣抽象类中可以没有抽象方法
4️⃣抽象类不能直接创建对象 (通过多态的形式创建方法,因为子类会重写抽象方法)
5️⃣继承抽象类 子类必须要实现 抽象类中的抽象方法
// 抽象举例
// 创建抽象父类 满足抽象注意事项 2️⃣
abstract class Animal{
public Animal() {
System.out.println("我是构造方法");
}
// 声明抽象方法 吃 满足抽象注意事项 1️⃣
public abstract void eat();
public void fun() {
System.out.println("我是fun方法");
}
}
// 创建子类
class Cat extends Animal{
// 实现抽象方法 满足抽象注意事项 5️⃣
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println("猫吃鱼");
}
public void zLS() {
System.out.println("抓老鼠");
}
}
// 创建对象
public class Demo {
public static void main(String[] args) {
// 抽象类能不能创建对象? 不能 因为无法调用抽象方法
// 抽象类有没有构造方法? 有
/* 满足抽象注意事项 4️⃣*/
// 抽象类该如何使用?
// 使用多态的形式 创建对象
Animal ainmal = new Cat();
ainmal.eat();// 成员方法编译看父类,运行看子类
// 向下转型 实现特有方法
Cat cat = (Cat)ainmal;
cat.zLS();
}
}
3.抽象类中 有哪些?
参考上述例子:
1️⃣常量 变量
2️⃣抽象方法
3️⃣成员方法
4️⃣构造方法
4.抽象关键词 abstract 与哪些关键词不能共用
private 不能
修饰抽象方法 子类不能实现 抽象方法没意义
final 不能
修饰抽象方法 方法不能被重写 抽象方法没意义
static 不能
修饰抽象方法 可以直接使用类名来调用 但是抽象方法没实现部分(抽象方法没功能)
模板设计模式
1.核心:
当你的程序大部分代码都相同,只有少部分需要修改时
可以使用模板设计模式(利用抽象类,抽象少部分代码,在子类重写那少部分代码)
// 模板设计模式举例: 大学选课,同专业选同一门课,但是学生选择的老师不同
// 创建 同专业类(只能一个)
abstract class Professional{
public void major(){
System.out.println("软件工程");
teacher();
}
// 抽象 老师方法(因为专业老师有很多,不易描述)
public abstract void teacher();
}
// 创建 学生类1(可以多个)
class Student1 extends Professional{
// 重写老师方法(选择了一个老师,易描述)
@Override
public void teacher() {
System.out.println("张三老师");
System.out.println("周三上课");
}
}
// 创建 学生类2
class Student2 extends Professional{
// 重写老师方法(选择了一个老师,易描述)
@Override
public void teacher() {
System.out.println("王四老师");
System.out.println("周四上课");
}
}
// 创建对象
public class Demo {
public static void main(String[] args) {
Professional one = new Student1();
one.major();
Professional two = new Student2();
two.major();
}
}
// 运行结果
软件工程 // 相同部分
张三老师 // 不同
周三上课 // 不同
软件工程
王四老师
周四上课
/*
* 实例:打印一个程序的执行时间(使用模板设计模式)
* 要点:抽象不同程序
*/
public class Demo {
public static void main(String[] args) {
/* // 获取系统当前时间
// 单位:毫秒
// 从1970年1月1号 到 现在的毫秒数
long time1 = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
System.out.println(i);
}
long time2 = System.currentTimeMillis();
System.out.println("程序执行了" + (time2 - time1) + "毫秒");
*/
Son aSon = new Son();
aSon.time();
}
}
abstract class Time{
public void time() {
// 初始时间
long time1 = System.currentTimeMillis();
chengxu();
long time2 = System.currentTimeMillis();
System.out.println("程序执行了" + (time2 - time1) + "毫秒");
}
public abstract void chengxu();
}
class Son extends Time{
// 要计算时间的程序
@Override
public void chengxu() {
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i ; j++) {
System.out.print(j + "*" + i + "=" + i*j + " ");
}
System.out.println();
}
}
}
接口[因为只能写抽象方法,所以使用多态创建对象]
1. 接口
1️⃣ 狭义的解释:
使用关键字 interface 来定义接口
interface 接口名{
}
2️⃣ 广义的解释:
接口相当于一个规则 需要人来遵守
2.注意事项
1️⃣接口 使用的不是继承
而是关键词 implements(实现)
2️⃣接口类不能直接创建对象
3️⃣接口类不能声明成员方法
4️⃣接口类不能声明构造方法
5️⃣使用多态形式创建对象
综上所得:
接口可以写:
1.只能写抽象方法
并且可以省略public abstract这两个关键词
2.只能写静态常量
并且可以省略public static final这三个关键词
// 举例:
// 声明一个接口 (相当于:制定了一份规则)
interface InterA{
(public static final) int num = 10;
// 抽象方法
(public abstract) void fun();
}
// 实现接口
// 规范: 实现类的类名 后缀 Impl
class InterAImpl implements InterA{
// 实现接口中的抽象方法
@Override
public void fun() {
// num = 14;
// TODO Auto-generated method stub
System.out.println(num);
System.out.println("我是实现类的fun方法");
}
}
// 创建 接口对象
public class Demo08 {
public static void main(String[] args) {
// 使用多态的形式 创建接口对象
InterA a = new InterAImpl();
a.fun();
System.out.println(InterA.num);
}
}
/*
* 动物(抽象类)
* 叫(抽象方法)
*
* 训练动物(规则)
* 说人话
*
* 猫
* 喵喵
*
* 家猫
*
* 蓝猫
* 训练说人话
*/
public class Demo09 {
}
// 声明动物抽象类
abstract class Animal{
// 声明叫 抽象方法
public abstract void speak();
}
// 声明猫类
class Cat extends Animal{
// 重写 叫抽象方法
@Override
public void speak() {
// TODO Auto-generated method stub
System.out.println("喵喵喵");
}
}
// 蓝猫类(继承猫类,实现规则说人话)
class BlueCat extends Cat implements InterCat{
// 实现接口中的方法
@Override
public void studySpeak() {
// TODO Auto-generated method stub
System.out.println("说人话");
}
}
// 声明接口(规则)
interface InterCat{
// 学习说人话
public abstract void studySpeak();
}