《Java编程思想》第10章 练习题

源代码地址:https://github.com/yangxian1229/ThinkingInJava
练习1:编写一个名为Outer的类,它包含一个名为Inner的类。在Outer中添加一个方法,它返回一个Inner类型的对象。在main()中创建并初始化一个指向某个Inner对象的引用。
练习2:创建一个类,它持有一个String,并且有一个显示这个String的toString()方法。将你的新类的若干个对象添加到一个Sequence对象中,然后显示它们。
练习3:修改练习1,使得Outer类包含一个private String域(由构造器初始化),而Inner包含一个显示这个域的toString()方法。创建一个Inner类型的对象并显示它。
练习4:在Sequence.SequenceSelector类中增加一个方法,它可以生成对外部类Sequence的引用。
练习5:创建一个包含内部类的类,在另一个独立的类中,创建此内部类的实例。

package ch10;
import ch10.E05A.Inner;
class E05A{
	public class Contents{
		Contents(){System.out.println("Contents");}
	}
	static class Inner{
		Inner(){System.out.println("Inner");}
	}
}

public class E05 {
	public static void main(String[] args) {
		E05A ea = new E05A();
		E05A.Contents ec = ea.new Contents();
		//static innerclass
		E05A.Inner ei = new Inner();
	}
}/* Output:
Contents
Inner
*///:~

练习6:在第一个包中创建一个至少有一个方法的接口。然后在第二个包内创建一个类,在其中增加一个protected的内部类以实现那个接口。在第三个包中,继承这个类,并在一个方法中返回该protected内部类的对象,在返回的时候向上转型为第一个包中的接口类型。
练习7:创建一个含有private域和private方法的类。创建一个内部类,它有一个方法可用来修改外围类的域,并调用外围类的方法。在外围类的另一个方法中,创建此内部类的对象,并且调用它的方法,然后说明对外围类对象的影响。
练习8:确定外部类是否可以访问其内部类的private元素。
:可以。
练习9:创建一个至少有一个方法的接口。在某个方法内定义一个内部类以实现此接口,这个方法返回对此接口的引用。
练习10:重复前一个练习,但将内部类定义在某个方法的一个作用域内。
练习11:创建一个private内部类,让它实现一个public接口。写一个方法,它返回一个指向此private内部类的实例的引用,并将此引用向上转型为该接口类型。通过尝试向下转型说明此内部类完全隐藏了。
练习12:重复练习7,这次试用匿名内部类。
练习13:重复练习9,这次试用匿名内部类。
练习14:修改interfaces/HorrorShow.java,用匿名类实现DangerousMonster和Vampire。
练习15:创建一个类,它有非默认的构造器(即需要参数的构造器),并且没有默认构造器。创建第二个类,它包含一个方法,能够返回对第一个类的对象的引用。通过写一个继承自第一个类的匿名内部类,来创建一个返回对象。

package ch10;

class E15A{
	E15A(int i){
		System.out.println("E15A:"+i);
	}
	void print(){
		System.out.println("Hello world!");
	}
}

class E15B{
	public E15A f(int i){
		return new E15A(i){};
	}
	public E15A f2(int i){
		return new E15A(i){
			void print(){
				System.out.println("E15B f2()");
			}
		};
	}
}

public class E15 {
	public static void main(String[] args) {
		E15A ea = new E15B().f(3);
		ea.print();
		
		E15A ea2 = new E15B().f2(233);
		ea2.print();
	}
}/* Output:
E15A:3
Hello world!
E15A:233
E15B f2()
*///:~

练习16:修改第9章中练习18的解决方案,让它使用匿名内部类。
练习17:修改第9章中练习19的解决方案,让它使用匿名内部类。
练习18:创建一个包含嵌套的类。在main()中创建其内部类的实例。
练习19:创建一个包含了内部类的类,而此内部类又包含有内部类。使用嵌套类重复这个过程。注意编译器生成的.class文件的名字。

package ch10;

public class E19 {
	class Inner1{
		class Inner2{
			void f(){}
		}
		Inner2 makeInner2(){return new Inner2();}
	}
	Inner1 makeInner1(){return new Inner1();}
	
	static class E19A{
		static class E19B{
			public void printB(){
				System.out.println("E19B Hello world!");
			}
		}
		public void printA(){
			System.out.println("E19A Hello world!");
		}
	}

	public static void main(String[] args) {
		new E19.E19A().printA();
		new E19.E19A.E19B().printB();
		E19 e = new E19();
		E19.Inner1 i1 = e.makeInner1();
		E19.Inner1.Inner2 i2 = i1.makeInner2();
	}
}/* Output:
E19A Hello world!
E19B Hello world!
*///:~

在这里插入图片描述
练习20:创建一个包含嵌套类的接口,实现此接口并创建嵌套类的实例。
练习21:创建一个包含嵌套类的接口,该嵌套类中有一个static方法,它将调用接口中的方法并显示结果。实现这个接口,并将这个实现的一个实例传递给这个方法。
练习22:实现Sequence.java中的reverseSelector()方法。
练习23:创建一个接口U,它包含三个方法。创建第一个类A,它包含一个方法,在此方法中通过创建一个匿名内部类,来生成指向U的引用。创建第二个类B,它包含一个由U构成的数组。B应有几个方法,第一个方法可以接受对U的引用并存储到数组中;第二个方法将数组中的引用设为null;第三个方法遍历此数组,并在U中调用这些方法。在main()中,创建一组A的对象和一个B的对象。用那些A类对象所产生的U类型的引用填充B对象的数组。使用B回调所有A的对象。再从B中移除某些U的引用。
练习24:练习25:看完22章回来看。
练习26:创建一个包含内部类的类,此内部类有一个非默认的构造器(需要参数的构造器)。创建另一个也包含内部类的类,此内部类继承自第一个内部类。

package ch10;

class E26A{
	class E26B{
		E26B(int i){
			System.out.println("E26B");
		}
	}
}

public class E26 extends E26A.E26B{
	E26(E26A ea){
		ea.super(1);
		System.out.print("E26");
	}
	public static void main(String[] args) {
		E26 e = new E26(new E26A());
	}
}/* Output:
E26B
E26
*///:~

猜你喜欢

转载自blog.csdn.net/lanzijingshizi/article/details/84324504