练习(1):编写一个名为Outer的类,它包含一个名为Inner的类。在Outer中添加一个方法,它返回一个Inner类型的对象。在main()中,创建并初始化一个指向某个Inner对象的引用。
public class Test1 {
class Inner{}
public Inner getInner(){
return new Inner();
}
public static void main(String[] args){
Test1 t = new Test1();
Inner i = t.getInner();
}
}
练习(2):创建一个类,它持有一个String,并且有一个显示这个String的toString()方法,将你的新类的若干个对象添加到一个Sequence对象中,然后显示它们。
public class Test2 {
private Object[] items;
private int next = 0;
public Test2(int size) {
items = new Object[size];
}
public void add(Object o) {
if (next < items.length) {
items[next++] = o;
}
}
//迭代器设计模式,对外公布一个选择器,可以按照你所设计的顺序访问内部的存储的数据
//外部使用者不需要关心该类的具体实现,体现了封装的原则
private class SequenceSelector implements Selector {//内部类,能访问外部类的所有成员
private int i = 0;
@Override
public boolean end() {
return i == items.length;
}
@Override
public Object current() {
return items[i];
}
@Override
public void next() {
if (i < items.length) {
i++;
}
}
}
public Selector selector() {
return new SequenceSelector();
}
public static void main(String[] args){
Test2 t = new Test2(10);
for (int i = 0; i < 10; i++) {
t.add(new myClass(i+""));
}
Selector selector = t.selector();
while (!selector.end()){
System.out.println(selector.current());
selector.next();
}
}
}
class myClass{
String str;
public myClass(String s){
str = s;
}
@Override
public String toString() {
return str + " " + str;
}
}
interface Selector{
boolean end();
Object current();
void next();
}
练习(3):修改练习1,使得Outer类包含一个private string域(由构造器初始化),而Inner包含一个显示这个域的toString()方法。创建一个Inner类型的对象并显示它。
public class Test1 {
private String str;
public Test1(String s){
str = s;
}
class Inner{
@Override
public String toString() {
return str;
}
}
public Inner getInner(){
return new Inner();
}
public static void main(String[] args){
String s = "lalalal";
Test1 t = new Test1(s);
Inner i = t.getInner();
System.out.println(i.toString());
}
}
练习(4):在Sequence.SequenceSelector类中增加一个方法,它可以生成对外部类Sequence的引用。
public Test2 getTest2(){//生成对外部类的引用
return Test2.this;//不需要外部类的实例
}
练习(5):创建一个包含内部类的类,在另一个独立的类中,创建此内部类的实例。
public class Test5 {
public static void main(String[] args){
Bird bird = new Bird();
Bird.Egg egg = bird.new Egg();//必须有外部类的实例才能创建内部类
}
}
class Bird{
class Egg{
public Egg(){
System.out.println("bird has an egg");
}
}
}
练习(6):在第一个包中创建一个至少有一个方法的接口。然后在第二个包内创建一个类,在其中增加一个protected的内部类以实现那个接口。在第三个包中,继承这个类,并在一个方法中返回该protected内部类对象,在返回的时候向上转型为第一个包中的接口的类型。
public class Test6 extends anclass {
public firstInter get(){
return this.new innerClass();//报错
return new innerClass();//此时编译器报错,该内部类是protected的,需要修改成Public才能用
}
}
练习(7):创建一个含有private域和private方法的类。创建一个内部类,它有一个方法可用来修改外部类的域,并调用外围类的方法。在外围类的另一个方法中,创建此内部类的对象,并且调用它的方法,然后说明对外围类对象的影响。
public class Test7 {
private String name ="weiwei";
private void sayHi(){
System.out.println("HI");
}
public void test(){
Test7Inner inner = new Test7Inner();
inner.name();
}
class Test7Inner{
public void name(){
name = "xu" + name;
sayHi();
}
}
public static void main(String[] args){
Test7 t = new Test7();
t.test();
System.out.println(t.name);
}
}
练习(8):确定外部类是否可以访问其内部类的private元素。
public class Test8 {
class T8inner {
private int count;
}
void add(){
T8inner inner = new T8inner();
inner.count++;
System.out.println(inner.count);//最后输出1,可见是可以操作的
}
public static void main(String[] args){
Test8 t = new Test8();
t.add();
}
}
练习(9):创建一个至少有一个方法的接口。在某个方法内定义一个内部类以实现此接口,该方法返回对此接口的引用。
练习(10):重复前一个练习,但将内部类定义在某个方法的一个作用域内。
public class Test9 {
private int count;
listner onClick() {
if (count > 5) {//在方法的某个作用域内
class clickListner implements listner {
@Override
public void doclick() {
System.out.println("doclick");
}
}
clickListner c = new clickListner();
return c;
}
return null;
}
public void add() {
count++;
}
}
练习(11):创建一个private内部类,让它实现一个public接口。写一个方法,它返回一个指向此private内部类的实例的引用,并将此引用向上转型为该接口类型。通过尝试向下转型,说明此内部类被完全隐藏了。
public class Test9 {
private class onClickListner implements listner{
@Override
public void doclick() {
System.out.println("click");
}
public void doOther(){
System.out.println("other");
}
}
public listner setOnClickListner(){
listner l = new onClickListner();
return l;
}
public static void main(String[] args){
Test9 t = new Test9();
listner l = t.setOnClickListner();
// l.doOther();//编译器报错,cannot resolve method。
}
}
练习(12):重复练习7,这次使用匿名内部类。
public class Test12 {
private int num = 3;
private void add(){
num++;
}
public anJiekou jiekou(){
return new anJiekou() {
@Override
public void change() {
num++;
add();
}
};
}
public void anotherM(){
anJiekou a = jiekou();
a.change();
}
public static void main(String[] args){
Test12 t = new Test12();
t.anotherM();
System.out.println("num" + t.num);
}
}
interface anJiekou{
void change();
}
练习(13):重复练习9,这次使用匿名内部类。
public class Test13 {
public Test13Jiekou setJiekou(){
return new Test13Jiekou() {
@Override
public void method() {
System.out.println("success");
}
};
}
public static void main(String[] args){
Test13 t = new Test13();
t.setJiekou().method();
}
}
interface Test13Jiekou{
void method();
}
练习(14):修改interface/HorrorShow.java,用匿名类实现DangerousMonster和Vampire。
interface/HorrorShow.java在P180
public class Test14 {
public Monster getDangerousMonster(){
return new Monster() {
@Override
public void menace() {
System.out.println("menace");
}
public void destroy(){//扩展的方法
System.out.println("destroy");
}
};
}
public Lethal getVampire(){
return new Lethal() {
@Override
public void kill() {
System.out.println("kill");
}
public void drinkBlood(){
System.out.println("dringkBlood");
}
};
}
}
interface Monster{
void menace();
}
interface Lethal{
void kill();
}
练习(15):创建一个类,它有非默认的构造器(既需要参数的构造器),并且没有默认构造器(没有无参数的构造器)。创建第二个类,它包含一个方法,能够返回对第一个类的对象的引用。通过写一个继承自第一个类的匿名内部类,来创建一个返回对象。
public class Test15 {
public Test15class gett15(String name){
return new Test15class(name){//继承自Test15class
void f(){
System.out.println("extends");
}
};
}
}
class Test15class{
private String name;
public Test15class(String str){
name = str;
}
}
练习(16):修改第九章中练习18的解决方案,让它使用匿名内部类。
public class Test16 {
public static void getAnCycle(CycleFactory factory){
Cycle c = factory.getCycle();
c.ride();
}
public static void main(String[] args){
getAnCycle(Unicycle.factory);
getAnCycle(Bicycle.factory);
getAnCycle(Tricycle.factory);
}
}
interface Cycle{
void ride();
}
interface CycleFactory{
Cycle getCycle();
}
class Unicycle implements Cycle{
private Unicycle(){}
@Override
public void ride() {
System.out.println("Unicycle ride");
}
public static CycleFactory factory = new CycleFactory() {
@Override
public Unicycle getCycle() {
return new Unicycle();
}
};
}
class Bicycle implements Cycle{
private Bicycle(){}
@Override
public void ride() {
System.out.println("Bicycle ride");
}
public static CycleFactory factory = new CycleFactory() {
@Override
public Cycle getCycle() {
return new Bicycle();
}
};
}
class Tricycle implements Cycle{
private Tricycle(){}
@Override
public void ride() {
System.out.println("Tricycle");
}
public static CycleFactory factory = new CycleFactory() {
@Override
public Cycle getCycle() {
return new Tricycle();
}
};
}
练习(17):修改第9章练习19的解决方案,让它使用匿名内部类。
public class Test19 {
public static void playGame(PlayGame p){
Game game = p.getGame();
game.play();
}
public static void main(String[] args){
playGame(PaoYingBi.playGame);
playGame(ZhiShaiZi.playGame);
}
}
interface Game{
void play();
}
interface PlayGame{
Game getGame();
}
class PaoYingBi implements Game{
private PaoYingBi(){}
@Override
public void play() {
System.out.println("抛硬币");
}
public static PlayGame playGame = new PlayGame() {
@Override
public Game getGame() {
return new PaoYingBi();
}
};
}
class ZhiShaiZi implements Game{
private ZhiShaiZi(){}
@Override
public void play() {
System.out.println("掷硬币");
}
public static PlayGame playGame = new PlayGame() {
@Override
public Game getGame() {
return new ZhiShaiZi();
}
};
}
练习(18):创建一个包含嵌套类的类。在main()中创建起内部类的实例。
public class Test18 {
static class Innerstatic{//静态内部类又称为嵌套类
private void f(){
System.out.println("innerstatic created");
}
private int anInt = 10;
}
public static void main(String[] args){
Innerstatic innerstatic = new Innerstatic();
//嵌套类不需要外部类的引用即可创建
}
}
练习(19):创建一个包含内部类的类,而此内部类又包含有内部类。使用嵌套类重复这回过程。注意编译器生成的.class文件的名字。
public class Test19real {
static class Birdd{
private String name;
public Birdd(String str){
name = str;
}
static class Chicken{
void eat(){
System.out.println("吃小米");
}
}
}
public static void main(String[] args){
Birdd.Chicken c = new Birdd.Chicken();
c.eat();
}
}
练习(20):创建一个包含嵌套类的接口,实现此接口并创建嵌套类的实例。
public class Test20 implements includeInner{
public static void main(String[] args){
inside i = new inside();
i.f();
}
}
interface includeInner{
class inside{
static void f(){
System.out.println("接口嵌套类内部静态方法");
}
}
}
练习(21):创建一个包含嵌套类的接口,该嵌套类中有一个static方法,它将调用接口中的方法并显示结果。实现这个接口,并将这个实现的一个实例传递给这个方法。
public class Test21 implements Dog{
@Override
public void bite() {
System.out.println("Test21");
}
public static void main(String[] args){
WangWang w = new WangWang();
w.f();
}
}
interface Dog{
void bite();
class WangWang implements Dog{
static void f(){
new WangWang().bite();
}
@Override
public void bite() {
System.out.println("bite");
}
}
}