提高代码质量 — 覆写变长方法也循规蹈矩

public class Parent {
	public void changedParamMethod(String... names){
		for(String name : names){
			System.out.println("hello parent: " + name);
		}
	}
	
	public void hello(String[] names){
		for(String name : names){
			System.out.println("hello son: " + name);
		}
	}
}

public class Son extends Parent {
	@Override
	public void changedParamMethod(String[] names){
		for(String name : names){
			System.out.println("hello son: " + name);
		}
	}
	@Override
	public void hello(String[] names){
		for(String name : names){
			System.out.println("hello son: " + name);
		}
	}
}

// 提高代码质量 -- 覆写变长方法也循规蹈矩
		Parent parent = new Son();
		parent.changedParamMethod("sss");
		parent.hello("sss");
		Son son = new Son();
		son.changedParamMethod("sss");

parent.changedParamMethod(“sss”);没有问题

son.changedParamMethod(“sss”);编译错误

parent.hello(“sss”);编译错误

按理说parent.changedParamMethod(“sss”)引用是son,调用son的方法发现是String[]应该有编译错误,但是这里JVM比较智能,能通过Parent将”sss”向上转型成{“sss”},但是son.changedParamMethod(“sss”)就不行了,parent.hello(“sss”)由于父类也是String[],所以当然会报错。

所以在重写的时候需要满足如下:

  • 重写方法修饰符访问权限不能缩小
  • 参数列表必须与重写方法相同
  • 返回类型必须与父类的返回相同或者是他的子类
  • 不能抛出新异常,可以少抛出异常

提高代码质量 — 避免null和空值威胁变长方法

public void changedParamMethod2(Integer... name){
		System.out.println("hello single: " + name);
	}
	public void changedParamMethod2(String... name){
		System.out.println("hello single: " + name);
	}

String[] strs = null;
		//baseService.changedParamMethod2(null);
		baseService.changedParamMethod2(strs);

因为JVM无法知道null的类型,而有多个变长方法满足所以系统无法找到相应的方法,baseService.changedParamMethod2(null);报错,要尽量避免多个符合的方法,不管是否有编译错误

提高代码质量 — 避免变长参数的方法重载

// 提高代码质量 -- 避免变长参数的方法重载
	public void changedParamMethod(String name){
		System.out.println("hello single: " + name);
	}
	public void changedParamMethod(String... name){
		System.out.println("hello complex: " + name);
	}
	
	public static void main(String[] args) {
		CodePromotingService1_30 baseService = new CodePromotingService1_30();
		baseService.changedParamMethod("aaa");
	}

baseService.changedParamMethod(“aaa”);两个方法都满足,JVM会根据简单原则先找到单一String参数的方法,虽然不会报错,但是变长参数对单一参数方法有覆盖的含义,在方法复杂的情况容易产生歧义。

边疆行 5 — 龙州探奇

龙州县位于广州西南部,西北于越南接壤,广西最早开放的通商口岸,有“小香港”之称,人口只有几万,左江横穿龙州县城,左江的龙州河段又被叫做丽江,发源于越南的水口河和平儿河,左江在状语里面有一个名字叫临尘,就是天上的河流的意思,在中法战争中,龙州就是作为一个重要的边陲的基地,击退了法国军队。民族英雄冯子才抗击法国取得胜利就是以龙州为重要的基地,不过后来清政府的腐败,还容许法国在龙州建立领事馆,使龙州被迫成为了广西最早开放的口岸。将要开通的南宁到凭祥的铁路将经过龙州。

  1. 鸡肉米粉
    龙州习惯早上吃米粉,受越南文化的影响,在吃米粉的时候会挤入桌上的柠檬的汁。有各种鸡肉米粉,热吃的,凉拌的都有。
  2. 法式建筑
    因为越南曾经长期是法国的殖民地,而龙州与越南相邻,也吸收了一些法国的文化。
  3. 美女村,美女泉
    因为村里人的体质和面容与众不同,皮肤很好,因此得名美女村,美女村也是长寿村,全村有好几位百岁老人,村里人都认为这些得源于美女泉。
  4. 古壮天琴
    天琴,当地壮语叫鼎叮,有上千年的历史,据传是古代巫师弹奏巫乐做法的时候的音乐,是一种悠远有神秘感的声音。
  5. 歌圩节
    歌圩是壮族聚会歌唱的一种传统习俗。
  6. 小连城
    中法战争时期的广西提督府,军事指挥中心,为了抵御法国的入侵,在小连成的将山山峰了修建了15座炮台,装上了德国的克虏伯大炮,正因为这些军事设施,让法国不能入侵成功,所以小连成有南疆长城的美誉。
  7. 水口口岸
    口岸的界碑是广西三大界碑之一
  8. 桄榔粉
    桄榔粉是从广西深山特有的桄榔树干加工成的,也被戏称为可以吃的木头,广西人有时喜欢把桄榔粉充的水充浓一点当早餐。
  9. 龙州砧板
    现在很多外地人知道龙州就是从龙州砧板开始的,砧板有名来源于做砧板的原料蚬木,质地坚硬,抗腐,抗磨,所以龙州砧板可以用好几十年,蚬木分布很窄,只在广西的龙州,宁明,西双版纳和越南北部海拔700以上的石灰岩区,而且生长缓慢,现在国内都很少了,所以需要从越南进口,

设计模式 — Facade外观模式

出现的背景:client端需要调用多个子模块实现某个功能,就需要有一个外观类来实现客户端对内部子模块api的解耦,因为其实客户端关注的只是需要实现某个功能,如果没有facasd类,那么相当于客户端需要知道moduleA提供了a零件,moduleB提供了b零件。。然后客户端要了解哪些module是自己这个功能需要的,还要自己组合才能得到想要的功能,而且一旦某几个module方法比如调用顺序发生改变,或者需要新的module方法实现一个新的细节,那么客户端也需要修改。

实现:

facade_1

 

facade_2

 

public class Facade {
	/**
	 * 示意方法,满足客户需要的功能
	 */
	public void test(){
		//在内部实现的时候,可能会调用到内部的多个模块
		AModuleApi a = new AModuleImpl();
		a.testA();
		BModuleApi b = new BModuleImpl();
		b.testB();
		CModuleApi c = new CModuleImpl();
		c.testC();
	}
}

public class Client {
	public static void main(String[] args) {
//		//不用Facade,需要自己跟多个模块交互
//		AModuleApi a = new AModuleImpl();
//		a.testA();
//		BModuleApi b = new BModuleImpl();
//		b.testB();
//		CModuleApi c = new CModuleImpl();
//		c.testC();
//		
//		System.out.println("使用Facade----------------------〉");
		//使用了Facade
		new Facade().test();		
	}
}

这样client只需要调用facade里面的方法就可以得到想要的功能而根本不需要知道具体由哪几个module来共同完成了这个功能

Facade加强版:

facade_3

 

这种模式是facade实现类同时被内部和外部调用,需要被外部调用的方法才封装成接口,这样能够屏蔽内部才调用的方法,使这些方法不会暴露到客户端,为了面向接口,不将内部的facade实现类暴露出去,所以还需要一个工厂来得到引起具体facade实例的facade接口对象。

Facade注意事项:

  • 有Facade类,但是客户端不是必须使用,客户端也可以直接使用具体的模块
  • Facade类只是对不同模块方法的封装,不需要自己去实现新的功能