一 单例模式
保证这个类只能构建一个对象
(1)构造器私有化
(2)静态的公共的访问方式
(3)提供一个私有的,静态的该类的引用
1.懒汉式:
调用功能获取对象时,才创建对象 ---线程不安全
代码
public class Single {
//2.提供一个私有的,静态的该类的引用
private static Single single=null;
//1.构造器私有化,外部不能使用
private Single(){
}
//3.静态的公共的访问方式
//锁方法
public synchronized static Single newInstance(){
if(single==null){
single=new Single();
}return single;
}
//锁块
public static Single newInstance(){
if(single==null){
synchronized(Single.class){
if(single==null){
single=new Single();
}
}
}
return single;
}
public void haha(){
System.out.println("hhhhhhhhhhhhhh");
}
}
2.饿汉式:
static修饰,类第一次加载时,就创建一个对象 ---所以线程安全
代码
public class SingleTon {
private static SingleTon singleTon=new SingleTon();
private SingleTon(){}
public static SingleTon newInstance(){
return singleTon;
}
}
二 静态代理模式
1.真实角色和代理角色要实现相同的接口|继承同一个父类
2.代理角色持有真实角色的引用
3.代理行为
优点:提高代码的复用性,便于代码后期的维护
代码
public class StaticProxy {
public static void main(String[] args) {
Manager manager=new Manager("李四");
HR hr=new HR(manager);
hr.addUser();
}
}
//招聘接口
interface AddUser{
void addUser();
}
//真实角色 项目经理
class Manager implements AddUser{
String name;
public Manager(String name) {
this.name=name;
}
@Override
public void addUser() {
System.out.println("面试录用....");
}
}
//代理角色
class HR implements AddUser{
//代理角色持有真实角色的引用
Manager manager=null;
public HR() {
// TODO Auto-generated constructor stub
}
public HR(Manager manager) {
this.manager=manager;
}
@Override
public void addUser() {
System.out.println("筛选简历 ");
System.out.println("通知面试");
manager.addUser(); //项目经理录用人
System.out.println("谈薪资");
System.out.println("签合同");
}
}
三 简单工厂模式
① 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑,用来创建产品
② 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。
③ 具体产品角色:工厂类所创建的对象就是此角色的实例。在 Java 中由一个具体类实现。
代码:
public class Factory {
public static void main(String[] args) {
// QQ qq=new QQ();
// qq.run();
Car car=carFactory("Auto");
car.run();
}
//工厂
public static Car carFactory(String type){
Car car=null;
if(type.equals("QQ")){
car=new QQ();
}else{
car=new Auto();
}
return car;
}
}
//父接口
interface Car{
void run();
}
//实现类 QQ
class QQ implements Car{
@Override
public void run() {
System.out.println("QQ在跑...");
}
}
//实现类 Auto
class Auto implements Car{
@Override
public void run() {
System.out.println("Auto在跑...");
}
}
四 内部类
内部类: 类中存在类,就是内部类
什么时候需要定义内部类:
在一个类中,内部的成员又是一个其他的事物,这个成员就可以定义为内部类
class Car{
class 发动机{
}
}
内部类的分类:
1.成员内部类
2.静态内部类
3.私有内部类
4.局部内部类
5.匿名内部类 (重点)
1.成员内部类:
在外部类的成员位置,定义的类,叫做成员内部类
即是成员也是类,既有成员的特性,能够使用成员修饰符(public ,static..),既然是类就有类的特性,类之间可以继承,可以实现接口
内部类中可以 使用外部类中的内容,包括私有
在成员内部类中只能定义静态的常量,其他静态内容不可以
在外部类中通过内部类的对象使用内部类中的内容
内部类编译后使用$表示
在其他类中如何使用内部类中的内容:
外部类 引用 = new 外部类();
外部类.内部类 引用 =引用.new 内部类();
外部类.内部类 引用 =new 外部类().new 内部类();
2.静态内部类
只能在静态的内部类中定义静态的内容,除了静态的常量
静态内部类可以定义静态的可以定义成员的
其他类中使用静态内部类中的内容:
外部类.内部类 引用 = new 外部类.内部类();
3.私有内部类
只能在外部类中通过私有内部类的对象使用私有内容
4.局部内部类
局部内部类:
局部:{}-->作用域
方法中的内部类-->局部内部类
注意:
局部内部类中的内容只能在当前所有在方法中通过对象使用
局部内部类不能使用成员修饰符,但是final可以
在局部内部类中使用当前所在方法的参数,需要把这个参数定义为final修饰,jdk1.7及之前必须显示定义final,1.8中可以省略final,默认存在
5.匿名内部类
为了简化代码,实现类子类没有使用多次的情况,可以使用匿名内部类简化
使用前提:必须是函数式接口(只有一个抽象类)
代码
public class Demo {
public static void main(String[] args) {
//Car car=new Car();
new Impl().run();
//匿名内部类
//1.没有引用指向 直接调用,用完销毁
new Car(){ //匿名内部类的类体,这个类体没有名字 Car匿名内部类实现的接口
@Override
public void run() {
System.out.println("3个轱辘的玛莎在跑...");
}
}.run();
//2.引用指向 多态 多次调用
Smoking s=new Smoking() {
@Override
public void smoke() {
System.out.println("边唱歌变抽烟...");
}
@Override
public void toSmokeCircle() {
System.out.println("吐心形的烟圈...");
}
};
s.smoke();
s.toSmokeCircle();
//多态
Car car=new Impl();
Zi zi=new Zi();
Smoking ss=new Smoking(){
@Override
public void smoke() {
}
@Override
public void toSmokeCircle() {
System.out.println("边敲代码边抽烟...");
}
};
//3. 匿名内部类 当做方法的参数使用
test(new Smoking(){
@Override
public void smoke() {
}
@Override
public void toSmokeCircle() {
System.out.println("边敲代码边抽烟...");
}
});
}
//匿名内部类可以作为方法的参数
public static void test(Smoking s){ //多态接收
s.toSmokeCircle();
}
}
//实现类 Impl
class Impl implements Car{
@Override
public void run() {
System.out.println("2个轱辘的玛莎在跑...");
}
}
//接口
interface Car{
void run();
}
class Zi extends Smoking{
@Override
public void smoke() {
// TODO Auto-generated method stub
}
@Override
public void toSmokeCircle() {
System.out.println("啦啦啦啦啦啦啦啦啦");
}
}
abstract class Smoking{
public abstract void smoke();
public abstract void toSmokeCircle();
}
6.Lambda表达式
jdk8新特性
(1)目的:
简化匿名内部类
(2)语法:
() -> {}
():抽象方法的参数列表
->: Lambda符号,箭头符号
{}:抽象方法的方法体实现
(3)Lambda使用前提:函数式接口
函数式接口:只有一个抽象方法的接口
检测函数式接口:@FunctionalInterface
(4)代码
A a=null;
a=new A(){
@Override
public void a(int a) {
System.out.println("我是匿名内部类的方法体实现");
}
};
a.a();
a=()->{System.out.println("我是Lambda的方法体实现");};
a.a();
a=(age)->{System.out.println("抽象方法存在一个参数,参数的数据类型可以省略,前后()可以省略"+age);};
a.a(20);
a=(age,height)->{System.out.println("抽象方法存在2个参数,参数的数据类型可以省略,前后的()不可以省略"+age+height);};
a.a(20,180);
a=(age,height)->System.out.println("抽象方法的方法体语句只有一句,前后的{}可以省略"+age+height);
//如果抽象方法有返回值,只有一条返回值语句,return和前后的{}都可以省略
a=(age,height)-> -111 ;
System.out.println(a.a(18,185));