class Art { Art(int a) { print("Art constructor "+a ); } Art() { print("Art constructor " ); } } class Drawing extends Art { Drawing(String aa) { super(1); print("Drawing constructor "+ aa); } Drawing() { print("Drawing constructor "); } } public class Cartoon extends Drawing { public Cartoon() { //super("zpc");//没有这句话则是一层一层调用默认的无参构造器,取消注释则调用指定的父类构造器 print("Cartoon constructor"); } public static void main(String[] args) { Cartoon x = new Cartoon(); } }
public class WithFinal extends MyFinal { private final void test(){ print("WithFinal.test"); } /*上面之所以能够"覆盖"test()方法只是因为private修饰的成员对子类是隐藏的, 这里不是覆盖,而是子类中创建的一个新的方法*/ /*public final void test2(){ print("WithFinal.test2"); } final修饰的方法不能被子类覆盖 */ public void test3(){ print("WithFinal.test3"); }//这里是方法覆盖,子类的修饰符要大于等于父类 } class MyFinal{ private final void test(){ print("MyFinal.test"); } public final void test2(){ print("MyFinal.test2"); } protected void test3(){ print("MyFinal.test3"); } }
//下面的代码引起空指针异常,因为先执行父类构造器,父类构造器中调用test方法实际却是调的子类覆盖的test方法,此时 //子类还没初始化,name值为null,把父类test方法改成private就行了,此时没有构成方法重写,父类构造器中test()直接调用Base类的test方法 public class Sub extends Base { String name="zpc"; public void test(){ System.out.println("子类重写父类的方法,name字符串的长度"+name.length()); } public static void main(String[] args){ Sub s=new Sub(); } } class Base{ public Base(){ test(); } public void test(){ System.out.println("将被子类覆盖的方法"); } }
//下面这个例子可以清晰展示初始化顺序,能更好地理解上面那个例子的过程 public class Sub extends Base { { System.out.println("Sub的普通初始化块"); } static { System.out.println("Sub的静态初始化块"); } String name="zpc"; public Sub(){ System.out.println("Sub()的构造函数"); } public static void main(String[] args){ Sub s=new Sub(); System.out.println("**************"); Sub s2=new Sub(); } } class Base{ static { System.out.println("Base的静态初始化块"); } { System.out.println("Base的普通初始化块"); } public Base(){ System.out.println("Base()的构造函数"); test(); } public void test(){ System.out.println("将被子类覆盖的方法"); } }
class Singleton{ //使用一个变量来缓存曾经创建的实例 private static Singleton instance; //隐藏构造器 private Singleton(){} //提供一个静态方法返回Singleton的实例 public static Singleton getInstance(){ if(instance==null){ instance=new Singleton(); } return instance; } } public class TestSingleton { public static void main(String[] args) { Singleton s1=Singleton.getInstance(); Singleton s2=Singleton.getInstance(); System.out.println("s1=s2?"+(s1==s2));//s1、s2指向同一个对象 } }45、final总结
public void fuzhi(final int d){ d=9;//非法,由调用方法时传入的参数完成初始化,不能再赋值 }(2)final方法
final修饰的类不可以被继承。
46、不可变类(未提供set方法,属性用private修饰)、重写equals方法、hashcode方法
//比较两个地址是否相等 public class Address { private final String detail; private final String postcode; public Address() { this.detail = ""; this.postcode = ""; } public Address(String detail, String postcode) { this.detail = detail; this.postcode = postcode; } public String getDetail(){return this.detail;} public String getPostcode(){return this.postcode;} public boolean equals(Object obj){ //重写Address类的equals方法 if(obj instanceof Address){ Address ad=(Address)obj; if(this.getDetail().equals(ad.getDetail())&&this.getPostcode().equals(ad.getPostcode())){ return true; } } return false; } public int hashCode(){ return detail.hashCode()+postcode.hashCode(); } public static void main(String[] args) { // TODO Auto-generated method stub Address ad1=new Address("南京","210046"); Address ad2=new Address("南京","210046"); System.out.println("a1==a2?"+(ad1==ad2)); System.out.println("a1.equals(a2)?"+ad1.equals(ad2)); System.out.println("ad1.hashcode:"+ad1.hashCode()); System.out.println("ad2.hashcode:"+ad2.hashCode()); } }
/* 命令模式测试*/ public class TestCommand { public static void main(String[] args) { ProcessArray pa=new ProcessArray(); int[] target={1,2,3,4}; pa.process(target, new PrintCommand()); pa.process(target, new SumPrintCommand()); } } class ProcessArray{ public void process(int[] target,Command cmd){ cmd.process(target); } } interface Command{ void process(int[] target); } class PrintCommand implements Command{ public void process(int[] target) { for(int temp:target){ System.out.println("迭代输出目标数组元素:"+temp); } } } class SumPrintCommand implements Command{ public void process(int[] target) { int sum=0; for(int t:target){ sum+=t; } System.out.println("目标数组元素之和:"+sum); } }
49、内部类实例 public class InnerClassTest { private String prop="外部类属性"; private class InnerClass{ private String prop="内部属性"; public void info(){ String prop="局部变量"; System.out.println("外部类属性值:"+InnerClassTest.this.prop); System.out.println("局部变量:"+prop); //先查局部变量、再到内部类找、再到外部类找 System.out.println("内部属性:"+this.prop); recall();//注意查找recall的顺序 InnerClassTest.this.recall(); } } public void info(){ new InnerClass().info(); } public void recall(){ System.out.println("内部类回调外部类方法"); } public static void main(String[] args) { // TODO Auto-generated method stub new InnerClassTest().info(); } }
class Out{ class In{ public In(String msg){ System.out.println(msg); } } //在外部类内部访问 In in=new In("外部类内部访问"); } public class CreateInnerInstance { public static void main(String[] args){ Out.In in=new Out().new In("测试"); /*等效于 * Out.In in; * Out out=new Out(); * in=out.new In("测试"); */ } } /*输出: 外部类内部访问 测试*/
interface Product{ public double getPrice(); public String getName(); } public class TestAnonymous { public void test(Product p){ System.out.println("购买了一个"+p.getName()+"花了"+p.getPrice()+"元"); } public static void main(String[] args) { TestAnonymous t=new TestAnonymous(); t.test(new Product() { public double getPrice() { // TODO Auto-generated method stub return 223.5; } public String getName() { // TODO Auto-generated method stub return "路由器"; } }); //上面使用匿名内部类的方式也可以换成如下实现方式 // class AnonymousProduct implements Product{ // public String getName() { // // TODO Auto-generated method stub // return "路由器"; // } // public double getPrice() { // // TODO Auto-generated method stub // return 223.5; // } // } // t.test(new AnonymousProduct()); } }