您的位置:首页 > 编程语言 > Java开发

接口(jdk1.8及之后) 单例模式(饿汉式,懒汉式) 静态代理模式 简单工厂模式 匿名内部类 lambda表达式

2020-01-15 11:40 302 查看

接口:

jdk1.8及之后新增了2种可以定义存在方法体的方法:
默认方法 (default关键字修饰的方法 )
使用:通过实现类对象使用
静态方法 (掌握)
使用:通过接口名去调用

目前接口中:

  1. 必须有抽象方法
  2. 可以有公共的静态常量
  3. 可以有静态方法
  4. 可以有默认方法

所以接口目前可以存在的方法有:抽象方法,静态方法,默认方法,和静态常量

public class Demo01 {
public static void main(String[] args) {
Demo001 d=new Demo001();
d.hehe();
Ab.haha();
}
}
interface Ab{
public static void haha(){//静态的接口方法通过类名调用
System.out.println("hahahahaha");
}
public default void hehe(){//默认的接口方法通过对象去调用
System.out.println("hehehehehe");
}
}
class Demo001 implements Ab {

}

单例模式

保证类只能存在一个实例

饿汉式 : 先创建对象,然后需要的人要这个对象,保证永远使用的都是这个创建好的对象–>线程安全的,效率相对较低; 类第一次加载完成之后就创建对象

懒汉式 : 当调用功能要对象的时候才会创建这个对象 --线程不安全,效率相对较高

实现单例 的类依旧可以正常定义其他内容,但是控制构造器,添加实现方式3步,保证这个类可以实现单例; 但是单例的类中定义的成员内容,在获取到该类对象后依旧可以正常使用

单例的实现方式:

  1. 构造器私有化
  2. 提供一个私有的静态的该类的引用
  3. 公共的访问方式(提供一个对象)

饿汉式:

public class Ehan {
public static void main(String[] args) {
Ehan e=Ehan.newInstance();//右边的对象赋值给左边
System.out.println(e);
System.out.println(e.newInstance());
System.out.println(e.newInstance());
}
private static Ehan e=new Ehan();//②私有的静态的创建对象
private Ehan() {//①私有的构造器
// TODO Auto-generated constructor stub
}
public static Ehan newInstance(){//③共公的访问方式  ->提供一个当前类型的对象  Instance是实例的意思
return e;
}
}

懒汉式:

public class LanHan {
private static LanHan lan=null;//②私有的静态的该类的引用
private LanHan(){//①私有的构造器

}
public static synchronized LanHan newInstance(){//③公共静态的的访问方式:保证懒汉式的线程安全问题: 给方法上一把锁,把方法中的代码范围锁住  synchronized,可以控制多个任务排队执行
if(lan==null){
lan=new LanHan();
}
return lan;
}
}

静态代理模式

1.真实角色 2.代理角色

增强代码程序的扩展性,便于后期维护,解耦

步骤:

  1. 真实角色和代理角色实现相同的接口(定义共同目标|行为)
  2. 代理角色持有真实角色的引用
  3. 代理行为

项目经理,HR 之间的例子

public class StaticProxy {
public static void main(String[] args) {
Manager manager=new Manager();
Hr hr=new Hr(manager);//有带参构造器
hr.addUser();//hr使用招聘功能
}
}
interface AddUser{//共同的接口
void addUser();
}
class Manager implements AddUser{//项目经理类,真实角色

public Manager() {
// TODO Auto-generated constructor stub
}
@Override
public void addUser() {
// TODO Auto-generated method stub

}

}
class Hr implements AddUser{//代理角色
Manager manager=null;//代理角色持有真实角色的引用;  先有对象声明,并赋值空值

public Hr() {
// TODO Auto-generated constructor stub
}
public Hr(Manager manager) {////创建hr对象的时候,就已经存在项目经理
super();
this.manager = manager;
}
@Override
public void addUser() {
System.out.println("发布招聘信息");
System.out.println("筛选简历");
manager.addUser();//Hr代理了管理者并使用招聘功能
System.out.println("谈薪资");
}
}

简单工厂模式:

抽象产品角色: 就是具体产品角色实现的接口|继承的父类

public class Factory {
public static void main(String[] args) {
Car car=factory("Baoma");
car.run();
}

public static Car factory(String s){
Car car=null;
if("Benchi".equals(s)){//s.equals("Benchi")不建议使用 ;这样空指针异常情况
car=new Benchi();
}else{
car=new Baoma();
}
return car;
}
}
interface Car{
void run();
}
//具体产品角色
class Benchi implements Car{

@Override
public void run() {
System.out.println("奔驰在奔驰..");

}

}
//具体产品角色
class Baoma implements Car{

@Override
public void run() {
System.out.println("宝马像宝马一样在奔跑..");

}

}

成员内部类:
成员内部类中不可以定义静态的内容,除非静态的常量

匿名内部类

内部类有类体,没有名字,这个类体我们称它为一个匿名内部类

简化类的结构:
当一个类没有自己本身的作用,只是想要使用一下类体的某个内容,并且也不会重复大量使用这个类,可以定义为一个匿名内部类,只在当前使用

public class AnonymousDemo {
public static void main(String[] args) {
Swim s=new Swim(){//可以通过引用多次调用接口中的功能

@Override
public void swimming() {
System.out.println("花样游泳");

}

@Override
public void noSwimming() {//新增方法
System.out.println("不会游泳");

}

};
s.swimming();
s.noSwimming();
test(new Swim(){//把匿名内部类的使用当做方法的参数
public void swimming() {
System.out.println("花样游泳");
}
public void noSwimming() {//新增方法
System.out.println("不会游泳");
}
});
}
static void test(Swim s){
s.swimming();
}
}
interface Swim{//游泳接口
void swimming();
void noSwimming();//新增方法
}

lambda表达式

jdk1.8推出的新特性,作用: 可以简化匿名内部类的使用

前提:函数式接口
函数式接口: 抽象方法只有一个的接口(接口中必须要重写的方法只有一个)
检查函数式接口: @FunctionalInterface

语法:
()->{}
( ): 重写的抽象方法的参数列表
->: 箭头符号, lambda 符号,箭头函数,具有上下文推到的作用
{ }: 重写的方法的方法体

public class LambdaDemo {
public static void main(String[] args) {
//匿名内部类的写法
/*Smoke s=new Smoke(){
@Override
public void smoking() {
System.out.println("边吸烟一遍吐烟圈...");
}
};*/

//lambda写法1:
/*Smoke s=()->{
System.out.println("边吸烟一遍吐心形烟圈...");
};*/

//lambda写法2: 当方法体语句只有一句的时候,前后的{}可以省略
//Smoke s=()->System.out.println("边吸烟一遍吐星星烟圈...");

//lambda写法3: 如果方法有参数,参数的数据类型可以省略
//Smoke s=(a,b)->System.out.println("边吸烟一遍吐星星烟圈..."+a);

//lambda写法4: 如果方法有参数,参数的个数只有一个,前后的()也可以省略
//Smoke s= a ->System.out.println("边吸烟一遍吐星星烟圈..."+a);

//lambda写法5: 如果方法有返回值类型,并且方法体只有一个return语句的时候,前后的{}+return关键字可以一起省略
/*Smoke s= a ->{
System.out.println("边吸烟一遍吐星星烟圈..."+a);
return "你好就好";
};*/
Smoke s= a ->"你好就好";
System.out.println(s.smoking(10));

//lambda可以当做方法的参数使用,前提形参的类型为一个函数式接口
test(a ->"你好就好");
}

static void test(Smoke s){
System.out.println(s.smoking(111));
}
}

//函数式接口
@FunctionalInterface
interface Smoke{
String smoking(int a);
}
  • 点赞 1
  • 收藏
  • 分享
  • 文章举报
Heiko_O 发布了25 篇原创文章 · 获赞 25 · 访问量 276 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐