唠唠SE的面向对象-02——封装

2. 封装

1) 我们日常使用的电脑主机,把cpu、内存、主板等等都封装到机箱里面去。假如没有机箱的话的出现什么问题?

主机、主板全部都散落在一处,然后开机没有开机按钮,那么需要我们直接操作接跳线才能把电脑开启。

这样子的话假如操作不慎的话,会让机器损坏危险,那么假如用机箱封装起来的话,那么就不需要这样子做了。这体现了封装的---安全特性

2) 你拿电脑去加内存,可以直接给电脑给维修的人。等他加好内存了之后,你拿到的还是那个机箱,里面发生了啥变化你并不知道。

封装的第二个好处---将变化隔离

3) 在机箱里面提供一个开机按钮,而不需要你直接使用跳线开机的话,体现了封装的---便于使用的特性。

4) 只要机箱提供了一个开机的功能,然后无论这个机箱拿到哪里去,都可以使用这个开机的功能。体现了封装的---可重复性的特性。

 

举个栗子:模拟员工类,看看封装与不封装有什么区别

不使用变量封装:

class Employee {
	String name;
	int age;
}

public class Test {
	public static void main(String[] args) {
		Employee employee = new Employee();
		employee.name = "辣条";
		employee.age = 24;
		System.out.println(employee.name);
	}
}

使用变量封装:

class Employee {
    private String name;
    private int age = 24;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
}

public class Test {
    public static void main(String[] args) {
        Employee employee = new Employee();
        //employee.name = "辣条"; -- 编译报错,变量被定义为private,不允许访问
        employee.setName("辣条");
        //employee.setAge(24); -- 报错,没有开放setter方法,不能修改age的值
        System.out.println(employee.getName());
    }
}

很容易发现被我注释掉的那两行都在编译期报错了,这就体现了封装的几个特性。

 

再举个栗子,说明封装的易操作:模拟一个手机,提供一个可以接收信息的方法

class Phone {
    private String name;
    private int price = 5000;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getPrice() {
        return price;
    }

    /**
     * 接收信息
     * @author LinkedBear
     * @param message 发送的信息
     */
    public void getMessage(String message) {
        System.out.println("价值" + price + "元的" + name + " 收到信息:" + message);
    }
}

public class Test {
    public static void main(String[] args) {
        Phone phone = new Phone();
        phone.setName("高端大气上档次的诺基亚黄屏手机");
        phone.getMessage("尊敬的用户您好,您的智商不足,请及时充值。。。");
    }
}

//运行结果:
//价值5000元的高端大气上档次的诺基亚黄屏手机 收到信息:尊敬的用户您好,您的智商不足,请及时充值。。。

 

我们再重复一遍 ̄へ ̄:

封装的好处:安全性、变化隔离、便于使用、可重复性

PS:封装之后的属性可以提供getter与setter方法来获取和修改。(setter还有一些东西,咱到后面说this的时候再唠)

 

咱来思考一个问题:

如果我们做这么一个功能:获取指定毫秒值对应的时间、日期等多种格式(可能部分代码不容易理解,我尽量把注释写清楚):

import java.text.SimpleDateFormat;
import java.util.Date;

public class Demo3 {
    public static void main(String[] args) {
        long time = System.currentTimeMillis(); // 用该方法可以获取当前时刻,精确到毫秒
        SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日"); // 用日期格式化类转换,格式为1970年01月01日
        SimpleDateFormat format2 = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒"); // 用日期格式化类转换,格式为1970年01月01日 12时00分00秒
        Date date = new Date(time); // 把毫秒值变成一个日期的对象
        System.out.println(format.format(date)); //转换,打印输出
        System.out.println(format2.format(date)); //转换,打印输出
        Date date2 = new Date();
        System.out.println(format.format(date2));
        System.out.println(format2.format(date2));
    }
}

//运行结果:
//2018年01月29日
//2018年01月29日 11时30分17秒
//2018年01月29日
//2018年01月29日 11时30分17秒

发现代码很多都重复了!

封装的第二种用途:提取相同/相似的代码,封装成一个方法

import java.text.SimpleDateFormat;
import java.util.Date;

public class Demo {
    public static void main(String[] args) {
        long time = System.currentTimeMillis(); // 用该方法可以获取当前时刻,精确到毫秒
        parseTimeToDate(time);
    }
    
    /**
     * 将一个毫秒值转换成年月日的字符串
     * @author LinkedBear
     * @param time 代表指定时刻的毫秒值
     */
    public static void parseTimeToDate(Long time) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒"); // 用日期格式化类转换,格式为1970年01月01日 12时00分00秒
        Date date = new Date(time); // 把毫秒值变成一个日期的对象
        System.out.println(format.format(date)); //转换,打印输出
    }
}

//运行结果:
//2018年01月29日 11时22分31秒

 

这样封装固然好,但是容易出现了一个新的问题:

如果我有一组实现效果相似的功能,总不能让我叫方法1,方法2,方法3吧,这也太low了!

所以,我们引入了下面的概念——

方法的重载Overload:

方法名相同,但传入参数的个数、类型、顺序不同,都可以用同名方法。

那我们再举一个栗子:上面的黄屏手机中新添加一个播放歌曲的无参方法,再添加一个指定播放曲目的有参方法

class Phone {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    
    /**
     * 无参方法,默认播放社会摇 ̄へ ̄
     * @author LinkedBear
     */
    public void music() {
        System.out.println(name + "正在播放:社会摇。。。");
    }
    
    /**
     * 带参方法,播放指定歌曲
     * @author LinkedBear
     * @Time 2018年1月29日 上午11:36:39
     * @param musicName
     */
    public void music(String musicName) {
        System.out.println(name + "正在播放:" + musicName);
    }
}

public class Test {
    public static void main(String[] args) {
        Phone phone = new Phone();
        phone.setName("高端大气上档次的诺基亚黄屏手机");
        phone.music();
        phone.music("一人饮酒醉");
    }
}

//运行结果:
//高端大气上档次的诺基亚黄屏手机正在播放:社会摇。。。
//高端大气上档次的诺基亚黄屏手机正在播放:一人饮酒醉

 

--------------------------------优雅的分割线------------------------------------

放在最后的,是我在实际开发中一直都在用的一个转换工具类,封装和重载的功能还是蛮够用的,贴出来分享一下吧 ̄へ ̄

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 转换工具类,支持时间格式转换、数字格式转换等
 * @author LinkedBear
 */
public class FormatUtil {
    public static final String DATE_PATTERN = "yyyy-MM-dd";
    public static final String TIME_PATTERN = "yyyy-MM-dd HH:mm";
    private static SimpleDateFormat formatDate = new SimpleDateFormat(DATE_PATTERN);
    private static SimpleDateFormat formatTime = new SimpleDateFormat(TIME_PATTERN);
    private static DecimalFormat df = new DecimalFormat("0.00");
    
    /**
     * 标准日期转换yyyy-MM-dd(接收Date)
     * @author LinkedBear
     * @param date
     * @return
     */
    public static synchronized String formatDate(Date date) {
        return formatDate.format(date);
    }
    
    /**
     * 标准日期转换yyyy-MM-dd(接收Long)
     * @author LinkedBear
     * @param date
     * @return
     */
    public static synchronized String formatDate(Long date) {
        return formatDate.format(new Date(date));
    }
    
    /**
     * 标准时间转换yyyy-MM-dd HH:mm(接收Date)
     * @author LinkedBear
     * @param date
     * @return
     */
    public static synchronized String formatMinute(Date date) {
        return formatTime.format(date);
    }
    /**
     * 标准时间转换yyyy-MM-dd HH:mm(接收Long)
     * @author LinkedBear
     * @param date
     * @return
     */
    public static synchronized String formatMinute(Long date) {
        return formatTime.format(new Date(date));
    }
    
    /**
     * 指定转换格式的日期转换(接收Date)
     * @author LinkedBear
     * @param date
     * @param pattern
     * @return
     */
    public static String formatDate(Date date, String pattern) {
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        return format.format(date);
    }
    /**
     * 指定转换格式的日期转换(接收Long)
     * @author LinkedBear
     * @param date
     * @param pattern
     * @return
     */
    public static String formatDate(Long date, String pattern) {
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        return format.format(new Date(date));
    }
    
    /**
     * 标准字符串日期yyyy-MM-dd转成Long
     * @author LinkedBear
     * @param date
     * @return
     */
    public static Long parseStringToLong(String date) {
        try {
            return formatDate.parse(date).getTime();
        } catch (ParseException e) {
            e.printStackTrace();
            return -1L;
        }
    }
    
    /**
     * 字符串时间转成指定格式的Long
     * @author LinkedBear
     * @param date
     * @param pattern
     * @return
     */
    public static Long parseStringToLong(String date, String pattern) {
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        try {
            return format.parse(date).getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return -1L;
    }
    
    /**
     * 将金额数值格式化为两位小数
     * @author LinkedBear
     * @param num
     * @return
     */
    public static synchronized String formatMoney(long num) {
        return df.format(num);
    }
    
    /**
     * 将金额数值格式化为两位小数
     * @author LinkedBear
     * @param num
     * @return
     */
    public static synchronized String formatMoney(double num) {
        return df.format(num);
    }
    
    private FormatUtil() {
        
    }
}

 

 

转载于:https://my.oschina.net/LinkedBear/blog/1614855

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值