Java内部类

将一个类的定义放到另一个类定义中,这个类就叫’内部类‘。内部类不是’合成‘,不是在类中声明一个指向别的对象的句柄。

class Outer {
	class Inner {
		void innerFun() {
			System.out.println("Inner");
		}
	}
	void outerFun() {
		System.out.println("Outer");
		Inner inner = new Inner();
		inner.innerFun();
	}
	Inner getInner() {
		return new Inner();
	}
	
	public static void main(String args) {
		//Inner inner = new Inner(); //You cannot create an inner object like this
		//Outer.Inner inner = new Outer.Inner(); //nor like this
		Outer outer = new Outer();
		//Outer.Inner inner = new outer.Inner(); //Nor like this
		Outer.Inner inner = outer.getInner(); //We can ceate an inner object like this
	}
}

1. 内部类和上溯造型(Upcasting)

我们可以通过内部类将接口(或者抽象类)的具体实现隐藏起来,只通过外部类方法返回实现了接口的内部类对象,调用者只能通过外部类获取类实例,而且此实例被以接口的句柄返回(内部类上溯到接口),调用者完全不知道类的实现细节和内部类的类型,只能通过接口调用内部类中实现的方法。外部类只能是public或者friendly的,而内部类还可以是private和protected的。

interface Runable {
	void run();
}

interface Eatable {
	void eat();
}

class Animal2 {
	class Dog implements Runable, Eatable {
		public void eat() {
			System.out.println("Dog is eating.");
		}
		public void run() {
			System.out.println("Dog is running.");
		}
	}
	
	class Cat implements Runable, Eatable {
		public void eat() {
			System.out.println("Cat is eating.");
		}
		public void run() {
			System.out.println("Cat is running.");
		}
	}
	
	public Dog getDog() { return new Dog(); }
	
	public Cat getCat() { return new Cat(); }
	
	public static void main(String args[]) {
		Animal2 animal = new Animal2();
		Runable runDog = animal.getDog();
		Eatable eatDog = (Eatable)runDog;
		
		Eatable eatCat = animal.getCat();
		Runable runCat = (Runable)eatCat;
	}
}

2. 方法里的内部类

下例中,内部类定义在方法里

interface Runable {
	void run();
}

interface Eatable {
	void eat();
}

class Animal3 {
	public Runable runDog() {
		class RunDog implements Runable {
			public void eat() {
				System.out.println("Dog is eating.");
			}
			public void run() {
				System.out.println("Dog is running.");
			}
		}
		
		return new RunDog();
	}
}


3. 方法作用域里的内部类

下例中内部类在一个if语句里

class Animal4 {
	private void eatingDog(boolean isDog) {
		if(isDog) {
			//Inner class in a field of a method
			class Dog {
				String name = "Dog";
			}
			
			Dog dog = new Dog();
			System.out.println(dog.name);
		}
	}
	
	public void dogEat(boolean isDog) {
		eatingDog(isDog);
	}
	
	public static void main(String args[]) {
		Animal4 animal = new Animal4();
		animal.dogEat(true);
	}
}


4. 匿名内部类

4.1 用于实现接口

下例用一个匿名类实现了接口Eatable,并将新类实例化上溯给Eatable句柄。注意类实现最后有一个分号,因为这个类实现其实是return表达式的一部分,Java表达式应该以分号结尾。

interface Eatable {
	void eat();
}

class Animal5 {
	public Eatable eatingCat() {
		return new Eatable() {
			public void eat() {
				System.out.println("Cat is eating");
			}
		}; //notice there is a ';'
	}
	
	public static void main(String args[]) {
		Animal5 animal = new Animal5();
		animal.eatingCat();
	}
}

4.2 用于扩展具有带参数构造方法的类

class BaseClass {
	int i = 0;
	public BaseClass(int x) { i = x; }
	public int getI() { return i; }
}

class ChildClass {
	public BaseClass base(int x) {
		return new BaseClass(x) {
			public int getI() {
				return super.getI()*20;
			}
		};
	}
	public static void main(String args[]) {
		ChildClass child = new ChildClass();
		BaseClass base = child.base(4);
	}
}

4.3 用于执行自定义字段初始化的匿名类

class BaseClass {
	int i = 0;
	public BaseClass(int x) { i = x; }
	public int getI() { return i; }
}

class ChildClass2 {
	public BaseClass base() {
		return new BaseClass(5) {
			String name = "Dog"; //Initiate parameter
			public String getName() { return name; }
		};
	}
}

4.4 通过实例初始化进行构造(匿名内部类不能有构造器)

class BaseClass {
	int i = 0;
	public BaseClass(int x) { i = x; }
	public int getI() { return i; }
}

class ChildClass3 {
	public BaseClass base() {
		return new BaseClass(10) {
			private String name;
			//instance initialization for each project
			{
				name = "Dog";
				System.out.println(name);
			}
			
			public String getName() { return name; }
		};
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值