EffectiveJava-类和接口

/*
 * 13
 * 使类和成员的可访问性最小化
 * 要区别设计良好的模块和设计不好的模块,最重要的因素在于,这个模块对于外部的模块而言,是否隐藏其内部实现和其它实现细节
 * 信息隐藏:降低模块之间的耦合度,使得模块可以独立的开发、测试、优化、使用、理解、修改,提高软件的可重用性
 * 实体的可访问性:实体声明的所在位置 和 访问修饰符
 * 
 * 对于顶层(非嵌套)的类和接口,只有两种可能的访问级别:public 和 default 公共和包级私有
 * default类:如果把类或者接口作为包级私有,它实际上成为包的实现的一部分而不是该包导出的API的一部分,在以后的发行版本中,
 * 进行修改、替换和删除不会影响到现有的客户端程序。
 * public类:导出的API的一部分,就有责任永远支持他以保证其兼容性。
 * protected类:导出的API的一部分,必须永远支持,导出的类的受保护成员代表了该类对于某个实现细节额公开承诺。(少使用)
 * 
 * 总之,设计一个最小的共有API后,应该防止把任何散乱的类、接口、成员变成API的一部分。
 * 除了共有的静态final域,共有类不应该包含共有域。并确保共有静态final域所引用的对象都是不可变。
 * 
 * 
 * 14
 * 在共有类中使用访问方法而非共有域
 * 

 * 
 * */
public class Item13_14 {
	private class B1{}
	protected class C1{}

}
class A{}
/*private class B{}报错
protected class C{}*/
class Point{
	private int x;
	private int y;
	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
	}
	public int getY() {
		return y;
	}
	public void setY(int y) {
		this.y = y;
	}
}


/*
 * 15
 * 使可变性最小化
 * 不可变类:其实例不能被修改的类,每个实例中包含的所有信息都必须在创建该实例的时候就提供,并在对象的整个生命周期内固定不变。
 * Java平台不可变类:String,基本类型包装类,BigInteger,BigDecimal
 * 
 * 不可变性
 * 不可变对象比较简单:不可变对象只有一种状态,即创建时状态,无需维护。可变对象可以有人以复杂的状态空间。
 * 不可变对象本质上是线程安全的,它们不要求同步。
 * 可以共享不可变对象及其内部信息。
 * 不可变对象为其它对象提供了大量的构件。
 * 缺点:对每个不同的值都需要一个单独的对象
 * 
 * 总之,坚决不要为每个get方法编写相应的set方法。
 * 除非有很好的理由让类成为可变的类,否则,应该是不可变的。
 * 除非有很好的理由让域成为非final的域,否则,应该是final域的。
 * */
public class Item15 {

}

//不可变类方法1
final class Complex{
	private final double re;
	private final double im;
	public Complex(double re, double im) {
		super();
		this.re = re;
		this.im = im;
	}
	public double getRe() {
		return re;
	}
	public double getIm() {
		return im;
	}
	
	public Complex add(Complex c){
		/*
		 * 创建一个新的Complex对象,而并非修改其实例。
		 * 函数的做法:返回一个函数的结果,这些函数对操作数进行运算但不修改它。---不可变性
		 * 过程的做法(命令的做法):将一个过程作用在它们的操作数上,导致其状态发生改变。
		 * */
		return new Complex(re+c.getRe(),im+c.getRe());
	}
	public Complex div(Complex c){
		return new Complex(re-c.getRe(),im-c.getRe());
	}
	@Override
	public String toString() {
		return "Complex [re=" + re + ", im=" + im + "]";
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		long temp;
		temp = Double.doubleToLongBits(im);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(re);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Complex other = (Complex) obj;
		if (Double.doubleToLongBits(im) != Double.doubleToLongBits(other.im))
			return false;
		if (Double.doubleToLongBits(re) != Double.doubleToLongBits(other.re))
			return false;
		return true;
	}
}
//不可变类-方法2
class Complex1{
	private final double re;
	private final double im;
	private Complex1(double re,double im){
		this.re=re;
		this.im=im;
	}
	public static Complex1 valueOf(double re,double im){
		return new Complex1(re,im);
	}
}

/*
 * 16
 * 复合优先于继承(inheritance)
 * 在包的内部使用继承是非常安全的,在那里,子类和超类 的实现都处在同一个程序员的控制之下;对专门为了继承而设计
 * 并且具有很好的文档类来说,使用继承也是非常安全的。
 * 然而,对于普通类的跨包边界的继承,是非常危险的。
 * 
 * 继承打破了封装性,超类的实现可能随着发行版本的不同而有所变化,此时,子类可能会遭到破坏,即使其代码没变。子类脆弱
 * 如果在超类的后续发行版本中获得了一个新方法,并且不幸的是,你给子类提供了一个签名相同但是返回类型不同的方法,这样的子类将无法通过编译。
 * 
 * 复合:不用扩展现有的类,而是在新的类中增加一个私有域,它引用现有类的一个实例。
 * 转发:新类中的每个实例方法都可以调用被包含的现有类实例中对应的方法,返回其结果。
 * 
 * 继承功能强大,但是存在许多问题,因为它破坏了封装性。
 * 只有当超类和子类之间存在is-a关系时,使用继承才恰当。即便如此,若处在不同的包中,并且超类不是为继承设计的,那么继承会导致脆弱性。
 * 为避免脆弱性,可使用复合转发机制来避免这种脆弱性,尤其是当存在适当的接口可以实现包装类的时候。包装类比子类更健壮,功能更强大。
 * */
public class Item16 {
public static void main(String [] args){
	InstrumentedHashSet<String> set = new InstrumentedHashSet<String>();
	set.add("a");
	set.addAll(Arrays.asList("b","c","d"));
	System.out.println(set.getCount());//7
	/*
	 * 在hashSet内部,addAll方法是基于其Add方法实现的---自用性(self-use)
	 * */
	
	InstrumentedHashSet1<String> set1 = new InstrumentedHashSet1<String>(new HashSet());
	set1.add("a");
	set1.addAll(Arrays.asList("b","c","d"));
	System.out.println(set1.getCount());//4
	
	
	
}
}

class InstrumentedHashSet<Object> extends HashSet<Object>{
	private int addCount=0;
	
	public InstrumentedHashSet(){}

	@Override
	public boolean add(Object e) {
		// TODO Auto-generated method stub
		addCount++;
		return super.add(e);
	}

	@Override
	public boolean addAll(Collection<? extends Object> c) {
		// TODO Auto-generated method stub
		addCount+=c.size();
		return super.addAll(c);
	}
	
	public int getCount(){
		return addCount;
	}
}


class ForwardingSet<Object> implements Set<Object>{
	
	private final Set<Object> s;
	public ForwardingSet(Set<Object> s){this.s=s;}

	@Override
	public int size() {
		// TODO Auto-generated method stub
		return s.size();
	}

	@Override
	public boolean isEmpty() {
		// TODO Auto-generated method stub
		return s.isEmpty();
	}

	@Override
	public boolean contains(java.lang.Object o) {
		// TODO Auto-generated method stub
		return s.contains(o);
	}

	@Override
	public Iterator<Object> iterator() {
		// TODO Auto-generated method stub
		return s.iterator();
	}

	@Override
	public java.lang.Object[] toArray() {
		// TODO Auto-generated method stub
		return s.toArray();
	}

	@Override
	public <T> T[] toArray(T[] a) {
		// TODO Auto-generated method stub
		return s.toArray(a);
	}

	@Override
	public boolean add(Object e) {
		// TODO Auto-generated method stub
		return s.add(e);
	}

	@Override
	public boolean remove(java.lang.Object o) {
		// TODO Auto-generated method stub
		return s.remove(o);
	}

	@Override
	public boolean containsAll(Collection<?> c) {
		// TODO Auto-generated method stub
		return s.containsAll(c);
	}

	@Override
	public boolean addAll(Collection<? extends Object> c) {
		// TODO Auto-generated method stub
		return s.addAll(c);
	}

	@Override
	public boolean retainAll(Collection<?> c) {
		// TODO Auto-generated method stub
		return s.retainAll(c);
	}

	@Override
	public boolean removeAll(Collection<?> c) {
		// TODO Auto-generated method stub
		return s.removeAll(c);
	}

	@Override
	public void clear() {
		// TODO Auto-generated method stub
		s.clear();
	}
}

class InstrumentedHashSet1<Object> extends ForwardingSet<Object>{
	
	private int addCount=0;

	public InstrumentedHashSet1(Set<Object> s) {
		super(s);
		// TODO Auto-generated constructor stub
	}
	
	@Override
	public boolean add(Object e) {
		// TODO Auto-generated method stub
		addCount++;
		return super.add(e);
	}

	@Override
	public boolean addAll(Collection<? extends Object> c) {
		// TODO Auto-generated method stub
		addCount+=c.size();
		return super.addAll(c);
	}
	
	public int getCount(){
		return addCount;
	}
	
}

/*
 * 17
 * 要么为继承而设计,并提供文档说明,要么禁止继承
 * 
 * 禁止子类化:final类	私有的构造方法和共有的静态工程
 * 
 * 
 * 18
 * 接口优于抽象类
 * 不严格的讲,mixin是指这样的类型:类除了实现它的基本类型之外,还可以实现这个mixin类型,以表明它提供了某些可供选择的行为。
 * 接口一般被公开放行,并且已经被广泛实现,再想改变这几接口几乎是不可能的。初次设计时保证接口的正确性。
 * 
 * 19
 * 接口只用于定义类型,不应该用来导出常量
 * 当类实现接口时,接口充当可以引用这个类实例的类型(type).因此,类实现了这个接口,表明客户端可以对类实例实施某些动作。
 * 
 * 常量接口模式:对接口的不良使用
 * */
public class Item17_18_19 {
	public static void main(String [] aegs){
		Sub s =new Sub();
		s.overrideMe();
//		Sub^^^null
//		Sub^^^Sat Jun 25 21:44:48 CST 2016
	}
}

class Super{
	/*
	 * 构造器绝不能调用可被覆盖的方法
	 * 超类的构造器在子类的构造器之前运行,所以,子类中覆盖版本的方法将会在子类的构造器运行之前就先被调用。
	 * 如果该覆盖版本的方法依赖于子类构造器所执行的任何初始化工作,该方法将不会如期执行
	 * */
	public Super(){
		overrideMe();
	}
	public void overrideMe(){
	}
}
final class Sub extends Super{
	private final Date  date;
	public Sub(){
		date = new Date();
	}
	@Override
	public void overrideMe() {
		// TODO Auto-generated method stub
		System.out.println("Sub" + "^^^"+date);
		//date.getTime();报错:超类构造器中,date域还没机会进行初始化
	}
	
} 

class Super1{
	public Super1(int a){}
}
class Sub1 extends Super1{
	public Sub1(int a) {
		super(a);//必须调用父类构造方法
		// TODO Auto-generated constructor stub
	}
}

class Super2{
	public Super2(int a){}
	public Super2(){}
}
class Sub2 extends Super2{

}

//常量接口
interface inA{
	double ERRWEW_QWEWE=1.123244234e-21;
	int ASD_QWE=12;
}

/*
 * 20
 * 类层次优于标签类
 * 标签类:冗长、易出错、效率低
 * 
 * */
public class Item20 {
	public static void main(String [] args){
		
	}

}
class Figure{
	enum Shape{Rectangle,Circle}
	final Shape shape;
	double width;
	double height;
	double radius;
	Figure(double width,double height){
		shape = Shape.Rectangle;
		this.width=width;
		this.height=height;
	}
	Figure(double radius){
		shape = Shape.Circle;
		this.radius=radius;
	}
	double area(){
		switch(shape){
		case Rectangle:return width*height;
		case Circle:return Math.PI*radius*radius;
		default:throw new AssertionError();
		}
	}
}
abstract class Figure1{
	abstract double area();
}
class Rectangle extends Figure1{
	double width;
	double height;
	Rectangle(double width,double height){
		this.width=width;
		this.height=height;
	}
	double area(){
		return width*height;
	}
}
class Circle extends Figure1{
	double radius;
	Circle(double radius){
		this.radius=radius;
	}
	double area(){
		return Math.PI*radius*radius;
	}
}

/*
 * 21
 * 用函数对象表示策略
 * 有些语言支持函数指针,代理,lambda表达式,或者支持类似的机制,允许程序把“调用特殊函数的能力”存储起来并传递这种能力。
 * 这种机制允许函数的调用者通过传入第二个函数,来制定自己的行为。
 * 
 * 函数指针的主要用途是实现策略模式。
 * 为了在java中实现这种模式,声明一个接口表示该模式,并为每个具体策略声明一个实现了该接口的类
 * 
 * 
 * 22
 * 优先考虑静态成员类
 * 嵌套类(nested class):制定在另一个类的内部的类,其目的应该只是为其外部类提供服务。
 * 静态成员类	非静态成员类	局部类	匿名类
 * 非静态成员类:非静态成员类的每个实例都隐含着与外围类的一个外围实例相关联。在没有外围类的情况下,不能创建非静态成员类
 * */
public class Item21_22 {
	public static void main(String [] args){
		Comparator c = new StringLengthComparator();
		c.compare("asd", null);
	}

}
//策略接口
interface Comparator<Object>{
	 int compare(Object t1,Object t2);
}
//具体策略实例1
class StringLengthComparator implements Comparator<String>{
	@Override
	public int compare(String t1, String t2) {
		// TODO Auto-generated method stub
		if( t1 == null || t2 == null) 
			throw new AssertionError();
		return t1.length()-t2.length();
	}
}
//具体策略实例2
class Host{
	private static class StrLenCmp implements Comparator<String>{
		@Override
		public int compare(String t1, String t2) {
			// TODO Auto-generated method stub
			if( t1 == null || t2 == null) 
				throw new AssertionError();
			return t1.length()-t2.length();
		}
	}
	public static final Comparator STRING_LENGTH_COMPARATOR = new StrLenCmp();
}


基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip基于MATLAB实现旅行推销员问题(TSP)的代码+项目说明(课程大作业)+测试数据.zip 【备注】 1、该资源内项目代码百分百可运行,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!
### 回答1: 《Effective Java第三版》是由Joshua Bloch所著的一本Java编程指南。这本书是基于第二版的更新版本,目的是给Java程序员提供一些最佳实践和经验,以编写高效、可维护和可靠的Java代码。 这本书共分为15个章节,每个章节都讲解了一个与Java开发有关的重要主题。比如,章节一讲述了使用静态工厂方法代替构造器的优点,章节二则介绍了如何用Builder模式来构建复杂的对象。此外,书中还提及了Java对象的等价性、覆盖equals方法和hashCode方法、避免创建不必要的对象、使用泛型、枚举、lambda表达式等等。 《Effective Java第三版》通过具体的代码示例和清晰的解释来说明每个主题的关键概念,使读者能够更好地理解和应用。此外,书中还提供了一些实用的技巧和技术,例如避免使用原始型、尽量使用接口而非来定义型等。 总的来说,这本书提供了很多实用的建议和技巧,可以帮助Java开发者写出高质量的代码。无论是初学者还是有经验的开发者,都可以从中受益匪浅。无论你是打算从头开始学习Java编程,还是已经有一定经验的开发者,这本书都是值得推荐的读物。 ### 回答2: 《Effective Java 第三版》是由Joshua Bloch 所著的一本Java编程指南,是Java程序员必读的经典之作。该书共包含90个条目,涵盖了各种Java编程的最佳实践和常见问题的解决方法。 本书分为多个部分,每个部分都侧重于一个特定的主题。作者探讨了Java编程中的各种问题和挑战,并提供了解决方案和建议。这些建议包括如何选择和使用合适的数据结构和算法,如何设计高效的接口,如何处理异常和错误,以及如何编写可读性强的代码等等。 《Effective Java 第三版》还关注了Java编程中的性能优化和安全性问题。作者强调了遵循Java语言规范、使用标准库、防范常见安全漏洞等重要原则。此外,本书还介绍了Java 8及其后续版本的新特性和用法,如Lambda表达式、流式编程和Optional等。 这本书的特点之一是每个条目都独立于其他条目,可以单独阅读和理解。每个条目开头都有一个简洁的总结,让读者能够快速掌握主要观点。此外,书中还有大量的示例代码和解释,帮助读者更好地理解和运用所学知识。 总的来说,《Effective Java 第三版》是一本非常实用和全面的Java编程指南。它适用于各个层次的Java程序员,无论是初学者还是有经验的开发人员,都可以从中获得宝贵的经验和知识。无论是编写高质量的代码、优化性能还是确保安全性,这本书都是一本不可或缺的参考书籍。 ### 回答3: 《Effective Java 第3版(中文版)》是由 Joshua Bloch 所著的一本关于使用 Java 编程语言的指南书。该书是对 Java 语言的最佳实践的详尽描述,为中高级 Java 开发人员提供了许多实用的建议和技巧。 该书的主要内容包括Java 语言的优雅编程风格、接口的设计、Lambda 表达式和流的使用、泛型、异常和并发编程等方面的最佳实践。 在《Effective Java 第3版(中文版)》中,许多传统的 Java 开发中的陷阱、常见错误和不良习惯都得到了深入的剖析和解答。它不仅提供了可供开发人员参考的示例代码,还解释了为什么某种方式是有问题的,以及如何更好地进行改进。 该书的深度和广度非常适合正在努力提高 Java 编程技能的开发人员。它涵盖了多个关键领域,为读者提供了在实际项目中解决常见问题的方法和思路。 此外,《Effective Java 第3版(中文版)》还介绍了最新版本的一些特性和改进。例如,它详细说明了如何正确地使用 Java 8 中新增的 Lambda 表达式和流,以及如何充分利用 Java 9、10 和 11 中的新功能。 总之,这本书是 Java 开发人员必备的指南之一。通过深入理解和应用书中的实践建议,读者可以更加高效地编写、优化和维护 Java 代码。无论是想提升职业技能还是在项目中减少错误和问题,这本《Effective Java 第3版(中文版)》都是一本非常有帮助的参考书。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值