Java学习23 2020-03-03

本文深入探讨了装饰者模式的应用与优势,通过实例展示了如何利用装饰者模式对现有功能进行扩展,同时介绍了DataOutputStream、DataInputStream及PrintStream的使用方法与应用场景。

内容

1.装饰者模式
2.DataOutputStream和DataInputStream
3.PrintStream

一.装饰者模式

1.对某一个类中的一个方法进行扩展

有两种方式
1.继承:这种方式虽然可以,但是有一个致命的弱点,就是使程序之间关联度比较高,很多情况下都不可取。
2.**装饰者模式 **

2.装饰者模式个人理解

①有一个装饰者(类)和一个被装饰者(也是类)。两者是关联关系而不是继承关系。装饰者中要含有被装饰者的引用,同时可以通过构造方法,使被装饰者的引用不为null。再在装饰者中写被扩展的方法(方法名要和被装饰者中的一致),里面要调用被装饰者的同名方法。这样,调用装饰者的那个方法就可以顺带着调用被装饰者的那个方法了。就实现了扩展。
②规范的应该类似于有一个接口(或者抽象类),装饰者和被装饰者都要继承这个抽象类,然后借助多态实现装饰者模式。这样做更加降低了程序之间的关联度

3.装饰者模式要求

1.装饰者中含有被装饰者的引用
2.装饰者和被装饰者应该实现同一个类型,同一个方法

4.使用示例(不是十分规范的,帮助理解)
package 对象;

import java.io.*;
import java.util.*;

public class 测试程序 {                                                                                                             
                                                                                                                        
    public static void main(String[] args) throws Exception {
   
        //1.创建被装饰者
        //A a = new A();
        
        //2.创建装饰者
        //B b = new B(a);
        
        //或者直接这样写
        B b = new B(new A());
        
        //3.通过执行装饰者中的方法间接去执行被装饰者中的方法
        b.close();
    }
}
/*
 * 输出结果
 *  扩展代码1
    A closed!
    扩展代码2

 */

//被装饰者
class A{
    public void close() {
        System.out.println("A closed!");
    }
}

//装饰者
class B{
    
    //两者是关联关系,而不是继承关系
    A a;//1.装饰者模式中要求,装饰者中含有被装饰者的引用
    
    //构造方法
    B(A a){
        this.a = a;
    }
    
    //对A中的close方法进行扩展
    public void close() {//2.装饰者模式中要求,装饰者和被装饰者应该实现同一个类型
        
        System.out.println("扩展代码1");
        a.close();
        System.out.println("扩展代码2");
    }
}
5.使用示例(更加规范的,用到多态,减少关联度)
package 对象;

import java.io.*;
import java.util.*;

public class 测试程序 {                                                                                                             
                                                                                                                        
    public static void main(String[] args) throws Exception {
   
        //1.创建被装饰者
        //A a = new A();
        
        //2.创建装饰者
        //B b = new B(a);
        
        //或者直接这样写
        B b = new B(new A());
        
        //3.通过执行装饰者中的方法间接去执行被装饰者中的方法
        b.close();
    }
}
/*
 * 输出结果
 *  扩展代码1
    A closed!
    扩展代码2

 */
//定义抽象类
abstract class C{
    public abstract void close();
}

//被装饰者
class A extends C{
    public void close() {
        System.out.println("A closed!");
    }
}

//装饰者
class B extends C{
    
    //两者是关联关系,而不是继承关系
    C a;//1.装饰者模式中要求,装饰者中含有被装饰者的引用
    
    //构造方法
    B(C a){//多态
        this.a = a;
    }
    
    //对A中的close方法进行扩展
    public void close() {//2.装饰者模式中要求,装饰者和被装饰者应该实现同一个类型
        
        System.out.println("扩展代码1");
        a.close();
        System.out.println("扩展代码2");
    }
}

二.DataOutputStream和DataInputStream

1.简单介绍

DataOutputStream是数据字节输出流
可以将内存中的类似"int i = 10"整个写入到硬盘文件中,写进去的不是字符串,而是二进制数据带类型,打开刚写入的文件是看不懂的,需要用DataInputStream打开才可以

2.使用示例
package 对象;

import java.io.*;
import java.util.*;

public class 测试程序   {                                                                                                             
                                                                                                                        
    public static void main(String[] args) throws Exception {
   
        //1.创建数据字节输出流
        DataOutputStream dos = new DataOutputStream(new FileOutputStream("temp06"));
        
        //2.准备数据
        byte b = 10;
        short s = 11;
        int i = 12;
        double d = 1.1;
        boolean bo = false;
        char c = 'a';
        
        //3.写入数据
        dos.writeByte(b);
        dos.writeShort(s);
        dos.writeInt(i);
        dos.writeDouble(d);
        dos.writeBoolean(bo);
        dos.writeChar(c);
        
        //4.刷新
        dos.flush();
        
        //5.关闭
        dos.close();
    }
}
文件内容看不懂
3.使用 DataInputStream打开

注意:要使用该流读取数据,必须提前知道该文件中数据的存储格式,顺序。也就是读的顺序必须和写入的顺序相同

package 对象;

import java.io.*;
import java.util.*;

public class 测试程序   {                                                                                                             
                                                                                                                        
    public static void main(String[] args) throws Exception {
   
        //1.创建输入流
        DataInputStream dis = new DataInputStream(new FileInputStream("temp06"));
        
        //2.读
        //注意:要使用该流读取数据,必须提前知道该文件中数据的存储格式,顺序。
        //也就是读的顺序必须和写入的顺序相同
        byte b = dis.readByte();//之前还得转换成字符串,现在直接就是Byte类型
        short s = dis.readShort();
        int i = dis.readInt();
        double d = dis.readDouble();
        boolean bo = dis.readBoolean();
        char c = dis.readChar();
        
        //3.输出
        System.out.println(b);
        System.out.println(s);
        System.out.println(i);
        System.out.println(d);
        System.out.println(bo);
        System.out.println(c);
        
        //4.关闭
        dis.close();
        
    }
}
/*
    10
    11
    12
    1.1
    false
    a
*/

三.PrintStream

1.简单介绍

java.io.PrintStream 是标准的输出流,默认以字节方式打印到控制台
java.io.PrintWriter 是以字符方式,这里不再讲。

2.使用示例

注意:不一定只能输出到控制台,也可以改变输出位置。
具体看下面代码

package 对象;

import java.io.*;
import java.util.*;
import java.text.*;

public class 测试程序   {                                                                                                             
                                                                                                                        
    public static void main(String[] args) throws Exception {
   
        //1.默认是输出到控制台的
        System.out.println("Helloworld!");
        
        //上面的代码也可以写成
        PrintStream ps = System.out;
        ps.println("哈哈");
        //不过一般选择连起来写
        
        //2.除了输出到控制台之外,也可以输出到其他地方,比如某个文件
        System.setOut(new PrintStream(new FileOutputStream("log")));//输出到log日志文件中
        
        //再次输出
        System.out.println("这一次输出到log文件中了");
        
        //3.通常使用上面这种方式来记录日志
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
        System.out.println("m1方法开始执行的时间是:" + sdf.format(new Date()));
        m1();
        System.out.println("m1方法执行结束的时间是:" + sdf.format(new Date()));
        
    }
    public static void m1(){
        System.out.println("m1方法执行");
    }
}
文件中的内容
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值