记录学习使用,欢迎留言讨论(如果想要知道完整的知识请查看java编程思想第七章的内容)
正确选择组合和继承
在开发中我们应该优先考虑组合,组合比继承要灵活的多,在有
- has-a:使用组合
- is-a:使用继承
代理
代理模式顾名思议就是代替一个类,替这个类做事情。(之后可以控制一些权限或者在执行方法前后加代码,spring中的aop底层就用到代理模式)
那么为什么需要代替这个类呢?
应用场景
应用场景:有用户类,用户类有一个id属性,评分,发博客两个方法。其中只能给别人评分,发博客也只能使用自己的用户发博客。
首先肯定有一个用户类,可供客户操作,其次有一个代理类其中实现给自己发博客但是不能给自己打分。
实现方法
将用户类抽象为一个接口UserInterface具有评分,发博客两个方法。
一个UserImpl类实现其所有方法。
再定义一个类UserProxy实现UserInterface接口,通过组合的方式将UserImpl实现类组合到此代理类中。
介绍:
- UserInterface——为接口
- UserImpl——被代理的类
- UserProxy——代理类(通过操作此类间接操作UserImpl类)
代码
MyTest
public class MyTest {
public static void main(String[] args) {
UserProxy userProxy = new UserProxy(9527);
userProxy.markSorce(9527);
userProxy.sendBlogs(9527);
/*
前置代码
不能给自己打分
后置代码
用户9527发送博客
*/
}
}
UserInterface
public interface UserInterface {
public void markSorce(int id);
public void sendBlogs(int id);
}
UserImpl
public class UserImpl implements UserInterface{
@Override
public void markSorce(int id) {
System.out.println("向用户"+id+"打分");
}
@Override
public void sendBlogs(int id) {
System.out.println("用户"+id+"发送博客");
}
}
UserProxy
public class UserProxy implements UserInterface{
private int MyId;
// 组合
private UserImpl userImpl;
// 初始化被代理类
public UserProxy(int MyId) {
this.MyId = MyId;
userImpl = new UserImpl();
}
@Override
public void markSorce(int id) {
// 在被代理类调用markSorce方法以前添加功能
System.out.println("前置代码");
if (id!=MyId) {
userImpl.markSorce(id);
}else {
System.out.println("不能给自己打分");
}
// 在被代理类调用markSorce方法以后添加功能
System.out.println("后置代码");
}
@Override
public void sendBlogs(int id) {
// 对userImpl.sendBlogs()添加权限判断
if (id==MyId) {
userImpl.sendBlogs(id);
}else {
System.out.println("不能给别人发博客");
}
}
}
final关键字
数据
- 基本类型:当用final修饰基本类型时代表此变量不变。
- 对象引用:当用final修饰对象引用时,此引用不得在指向其他对象,但是对象中的数据是可变的
- 空白final:可以先用final修饰然后再赋值。
小知识点:final和static联用时,每个对象共享此常量(在最开始初始化后就不能再变)。只有final时每个对象一个常量。
方法
使用final修饰方法的原因有两个:
- 将方法锁定,防止继承类修改它
- 提升效率。(现在应该考虑第一个原因才用final修饰方法了)
小知识点:用private修饰方法时,其隐式的使用final修饰。
类
用final修饰类时代表此类不能被继承。
初始化及类的加载
注意基类和子类的静态资源在使用new以前就初始化了,是因为调用了main方法,main方法是Base2的静态方法。
public class Base2 extends Base{
public static int base2 = printInit("Base2.base2初始化");
public Base2() {
System.out.println("Base2构造器");
}
public static void main(String[] args) {
// 先加载Base2.class,通过extends发现有父类跳到
// Base.class文件加载Base按顺序初始化static
System.out.println("————————————开始试验————————————");
// 使用构造器
// 构造器也是隐式的static也会触发Base2中static的初始化
// 但是static只初始化一次
// 构造器也是先进入Base2中再隐式的调用Base的构造器了
Base2 base2 = new Base2();
/*
Base.base初始化
Base2.base2初始化
————————————开始试验————————————
Base构造器
Base2构造器
*/
}
}
class Base{
public static int base = printInit("Base.base初始化");
public static int printInit(String s) {
System.out.println(s);
return 11;
}
public Base() {
System.out.println("Base构造器");
}
}