Java基础进阶
Java对象中的四大特性:
java中对象特性可从如下两点进行理解:
- 核心特性:封装,继承,多态
- 扩展特性:组合,例如圆(Circle)中有圆心(Point)
1.封装特性
- 广义封装:一个项目有哪些系统构成,一个系统由哪些模块构成,...
- 狭义封装:对象属性私有化,方法能公开则公开.
封装案例应用分享:
生活中的封装:
- 广义:大到国家有多个省份,小到家庭有多少个成员.
- 狭义:每个人都有特征(个头高,帅气,漂亮),都有行为(说话,跳舞,唱歌).
框架中的封装:
- mybatis:(封装JDBC操作,对JDBC参数处理,结果处理做了减法设计)
- 广义:(会话管理,连接池模块,缓存处理模块,日志模块处理,...)
- 狭义:SqlSession对象中应该有什么(,哪些设计为私有,哪些设计为公开)
- Spring:(封装了对象的创建,对象的管理)
- 广义:(IOC,MVC,AOP,…)
- 狭义:(ClassPathXmlApplicationContext对象的构成)
思考:
- 如何实现一个权限管理系统?(对用户进行权限控制)
- 如何实现一个商品评价系统?(商品模块,评价模块,日志模块)
2.继承特性
- 优势:实现代码的复用,提高程序的扩展性.(案例分析:自定义ClassLoader,参考框架mybatis,spring或tomcat中间件中的实现)
- 劣势:大范围扩展可能会导致类爆炸,会降低代码的可维护性.
继承应用案例分享:
1)生活中的继承:
- 子承父业
- 文化传承
2)框架中的继承:
-
- Mybatis(ContextMap,PersistenceException...)
- Spring (ManagedList,FlashMap,AnnotationAttributes....)
课堂练习:(经常在笔试中出现)
如何基于LinkedHashMap实现一个LRU算法(缓存淘汰算法)的Cahce对象?
提示:(方法:通过继承)
知识点引入:
//就是两种方法,进行自己调用方法
package com.java.oop.features;
import java.util.LinkedHashMap;
//自定义Lrucache对象(通过继承)
import org.apache.catalina.webresources.Cache;
class LruCache extends LinkedHashMap<String, Object>{
//添加序列化的id值
private static final long serialVersionUID = 1L;
private int maxCap;
//将类定义为外部类进行实现
public LruCache(int maxCap) {
super(maxCap,0.75f,true);
this.maxCap=maxCap;
}
//重写移除的方法
@Override
protected boolean removeEldestEntry(java.util.Map.Entry<String, Object> eldest) {
return size()>maxCap;
}
//添加线程安全的知识点
@Override
public synchronized Object put(String key, Object value) {
return super.put(key, value);
}
@Override
public synchronized Object get(Object key) {
return super.get(key);
}
}
public class TestLruCache01 {
public static void main(String[] args) {
//doTestlinkedHashMap01();
testLruCache();
}
public static void testLruCache() {
LruCache cache=new LruCache(3);
cache.put("A", 100);
cache.put("B", 200);
cache.put("C", 300);
cache.get("A");
cache.put("D", 400);
System.out.println(cache);
}
private static void doTestlinkedHashMap01() {
//LinkedHashMap双链表既可以记录存储的数据的顺序,同样可以记录读取数据的顺序
LinkedHashMap<String, Integer> map=
new LinkedHashMap<String, Integer>(
3,//初始容量
0.75f,//加载因子
//false代表的是添加顺序,true代表的是访问的顺序
//true访问数据的显示是最近访问的数据在最后的数据进行显示
true){
//添加序列化的ID
private static final long serialVersionUID = 1L;
@Override
/*此方法每次在执行put方法时都会执行
* 方法返回true时
* 就会将eldest元素进行移除
*/
protected boolean removeEldestEntry(java.util.Map.Entry<String, Integer> eldest) {
return size()>3;
}
};
//LinkedHashMap
/*
* 1.数据结构:链表+散列表
* 2.算法:记录元素的添加顺序,记录元素的读取的顺序
*
*/
map.put("A", 100);
map.put("C", 200);
map.put("D", 300);
map.put("B", 400);
System.out.println(map.get("B"));
System.out.println(map);
}
}
作业:进行自己构建先进先出算法,构建一个FIFOCache对象?
3.多态特性
a)编译时多态:方法的重载(名字相同,参数列表不同)
b)运行时多态:同一个行为(方法),因对象不同表现结果可能不同.
说明:此特性基于继承特性,父类引用可以指向子类对象,基于此特性可以更好实现程序之间的解耦合,提高程序可扩展性.
多态案例应用分享:
1)生活中多态:
a) 睡觉:有的人磨牙,有的人说梦话,有的人打呼噜,有的人梦游,...
b) 吃饭:有的人细嚼慢咽,有的人狼吞虎咽,...
2)框架中多态:
a)Mybatis (Executor,SimpleExecutor,CachingExecutor)
b)Spring (BeanbFactory,ClassPathXmlApplicationContext,...)
小知识点:
多态实现的时候,编译期看等号的左面
多态应用场景:
- 方法的返回值类型能用抽象则用抽象.
- 方法的参数类型能用抽象则用抽象.
扩展性应用
组合特性可以理解为面向对象中的一个扩展特性,即可多个对象通过相互关联(协同),共同完成一个业务模块功能.
为什么要组合(相互关联)呢?
1)类设计时要遵循单一职责原则,即类设计时不要设计大而全的对象,对象职
责越多引起类变化的原因就会更多。
2)类设计要各司其职,各尽所能,这样的可扩展性和维护性都会比较好。
组合案例应用分享:
1)生活中的组合:
- 陆海空,公检法
- 游戏中CS战队
例如:
package com.java.oop.features.compose;
class Person{}
class Male extends Person{}//is a
class Famale extends Person{} //is a
class Family{
//has a
private Male male;
//has a
private Famale famale;
}
public class TestCompose02 {
public static void main(String[] args) {
///use a System对象
System.out.println("compose");
}
}
2)程序或框架中的组合:
- 如何执行一个JDBC操作?(Connection,Statement,ResultSet相互组合)
- 如何完成一个MyBatis操作?
(SqlSessionFactory,SqlSession,Executor,.)
- Spring框架可以理解为一个资源整合框架,通过资源整合(组合)完成具体的业务功能.
课堂案例:
- 编写一个邮件发送业务,通过组合方式实现日志功能扩展.
package com.java.oop.features.compose;
interface MailService{
//创建一个接口,进行书写一个方法
void send(String msg);
}
class DefaultMailService implements MailService{
//实现类中的方法
final public void send(String msg) {
System.out.println("send"+msg);
}
}
//有final进行修饰如何进行继承类的关系,利用组合的方法
class LogMailService implements MailService{
private MailService mailService;
public LogMailService (MailService mailService) {
this.mailService=mailService;
}
public void send(String msg) {
System.out.println("start:"+System.nanoTime());
mailService.send(msg);
System.out.println("end:"+System.nanoTime());
}
}
public class TestCompose03 {
public static void main(String[] args) {
LogMailService logMailService=
new LogMailService(new DefaultMailService());
logMailService.send("1905 全部高薪就业");
}
}
- 编写一个基于组合方式实现的FifoCache对象(先进先出).
package com.java.oop.features.compose;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
class FifoCache{
//构建一个先进先出的缓存的对象,进行存储数据(满的时候先进行移除先放进的对象)
//借助此对象进行缓存数据
private Map<String, Object> cache;//无序数据
//借助LinkedList记录key的添加顺序
private LinkedList<String> keyList=
new LinkedList<String>();
//进行定义最大的容量
private int maxCap;
public FifoCache(int maxCap) {
this.maxCap=maxCap;
cache=new HashMap<String, Object>(maxCap);//无序数据
}
//负责将数据存储到cache
public void put(String key,Object value) {
//1.记录key的顺序(将添加的元素永远的放在队尾)
keyList.addLast(key);
//2.判定容器是否满了,满了则移除
if (keyList.size()>maxCap) {
//2.1从队列移除第一个key
String fristkey = keyList.removeFirst();
//2.2从cache中移除对象
cache.remove(fristkey);
}
//3.添加新的元素
cache.put(key, value);
}
@Override
public String toString() {
return "FifoCache [cache=" + cache + ", keyList=" + keyList + ", maxCap=" + maxCap + "]";
}
}
public class TestFifoCache01 {
public static void main(String[] args) {
FifoCache fifoCache=new FifoCache(2);
fifoCache.put("A", 100);
fifoCache.put("B", 200);
fifoCache.put("C", 300);
System.out.println(fifoCache);
}
}
- 编写一个基于组合方式实现的LruCache对象(作业).
课后作业:定义系列Cache类型对象
- 定义Cache接口
- 定义基于Cache接口的实现类,例如FIFOCache, PerpetualCache等
- 基于组合方式实现对象功能增强,参考如下图的设计
- JAVA中的两大抽象类型
Java中提供了两大抽象类型
- 接口(interface)
- 抽象类(abstract)
接口:定义规范,标准.(例如javax.sql.DataSource)
- 解耦(对象之间存在耦合时尽量耦合于接口):解耦并不是没有耦合
- 扩展(一个接口可以有很多不同实现类,例如List)
接口案例应用分享:
- 生活中的接口:usb接口,汽车引擎接口,...
- 程序中的接口:
- JDK:javax.sql.DataSource
- MyBatis:SqlSessionFactory,SqlSession,Executor,...
- Spring:BeanFactory,ApplicationContext
案例实现:基于JdbcTemplate实现数据访问操作
其中:
- DataSourceFactory 用于创建连接池(DataSource)对象
- JdbcTemplate 耦合于DataSouce接口
扩展:JDK8接口中可以定义静态方法以及默认(default)方法.