Java编程思想学习笔记——7.0复用类

本文探讨了Java编程中优先选择组合而非继承的原则,解释了代理模式的概念及其在权限控制中的应用。通过示例展示了如何实现用户评分和发博客功能的代理类。同时,讲解了final关键字在变量、方法和类中的作用,以及类的初始化和加载过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

记录学习使用,欢迎留言讨论(如果想要知道完整的知识请查看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关键字

数据

  1. 基本类型:当用final修饰基本类型时代表此变量不变。
  2. 对象引用:当用final修饰对象引用时,此引用不得在指向其他对象,但是对象中的数据是可变的
  3. 空白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构造器");
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值