天天看点

Java 编程思想 - 第十章 内部类第十章 内部类

Think in Java

  • 第十章 内部类
    • 1.创建内部类
    • 2.链接外部类
    • 3.使用.this与.new
    • 4.在方法和作用域内的内部类
    • 5.嵌套类
      • 5.1 接口内部的类
      • 5.2 多层嵌套类
    • `6. 为什么需要内部类`
    • 7. 内部类的继承
    • 8. 内部类的覆盖
    • 9. 局部内部类
    • 10. 内部类标识符

第十章 内部类

  • 可以讲一个类的定义放在另一个类的定义内部,这就是内部类。

1.创建内部类

public class InnerTest{
	public static void main(String[] args) {
		Outer o = new Outer();
		Inner inner = o.getInner();
		inner.say();
	}
}
class Outer {
	class Inner{
		public void say() {
			System.out.println("Hello World!");
		}
	}
	public Inner getInner() {
		Inner inner = new Inner();
		return inner;
	}
}
           

2.链接外部类

  • 内部类能与外部类通信,可以访问外部类的元素。

3.使用.this与.new

  • 如果内部类需要生成对外部类的引用,则可以在外部类的名字后紧跟.this,这样产生的引用自动的具有正确的类型,且这点在编译时期就被知晓并受到检查,因此不会受到额外的运行开销。

piblic class Outer{
	void say(){
		System.out.print("Outer.say()");
	}
	class Inner{
		public Outer getOuter(){
			return Outer.this;
		}
	}
	public Inner getInner(){
		return new Inner();
	}
	public static void main(String[] args){
		Outer o = new Outer();
		Outer.Inner i = o.getInner();
		i.getOuter().say();
	}
}
           
  • 如果要创建某个类的内部类,不能直接使用“外部类.内部类”,而是需要使用.new语法。例如:“外部类.new 内部类()”

4.在方法和作用域内的内部类

public class Outer{
	void say(){
		System.out.print("Outer.say()");
	}
	class Inner{
		public String say(){
			return "Inner";
		}
	}
	public Inner getInner(){
		//匿名内部类
		return new Inner() {
			@Override
			public String say() {
				return "Method Inner";
			}
		};
	}
	public static void main(String[] args){
		Outer o = new Outer();
		Outer.Inner i = o.getInner();
		System.out.println(i.say());
		System.out.println(o.new Inner().say());
	}
}
/*output:
Method Inner
Inner
*/
           
  • 匿名类是不能有名字的类,它们不能被引用,只能在创建时用new语句来声明它们。

5.嵌套类

  • 如果不需要内部类对象与其外部类对象之间有联系,那么可以将内部类声明为static。这通常称为嵌套类。

  • 嵌套类意味着:1).创建嵌套类对象,不需要使用外部类对象,可以直接创建。2).不能在嵌套内部类中访问非静态的外部类成员。

    嵌套内部类与普通内部类的区别:普通内部类的字段与方法只能放在类的外部层次上,所以普通的内部类不能有static数据和static字段,也不能包含嵌套类。但是嵌套类可以包含这些东西。

5.1 接口内部的类

  • 正常情况下,接口内部是不能放置任何代码的,但是嵌套类可以作为接口的一部分。接口中的任何类都自动是被public和static修饰。嵌套类是static的,所以并不违反接口的规则,甚至可以在嵌套类上实现外部接口。
  • 如果想要创建某些公共代码,使他们可以被某个接口的所有不同实现所公用,那么使用接口内部的嵌套类会很方便。
public interface OuterInteface{
	void say();
	class Inner implements Outerface{
		public void say(){
			System.out.print("Hello!");
		}
		public static void main(String[] args){
			new Inner().say()
		}
	}
}
/*output
Hello!
*/
           

5.2 多层嵌套类

  • 一个内部类被嵌套多少层并不重要,它能透明地访问所有它所嵌入的外部类的所有成员。

6. 为什么需要内部类

  • 内部类有效的实现了“多重继承”。

  • 每个内部类都能独立地继承自一个(接口)的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类没有任何影响。
  • 如果不需要解决“多重继承”的问题,那么可以用别的编码方式。但如果要使用内部类,还可以获得一些其他特性:1). 内部类可以有多个实例,每个实例都有自己的状态信息,并且与其外部类对象的信息相互独立。 2). 在单个外部类中,可以让多个内部类以不同的方式实现同一个接口,或继承同一个类。 3). 创建内部类对象的时刻并不依赖外部类对象的创建。 4). 内部类并没有令人迷惑的“is-a”关系,它就是一个独立的实体

7. 内部类的继承

class Outer{
	class Inner{}
}
public class InnerSon extends Outer.Inner{
	InnerSon(Outer out){
		out.super();
	}
	public static void main(String[] args){
		Outer o = new Outer();
		InnerSon i =  new InnerSon(o);
	}
}
           

8. 内部类的覆盖

  • 可以被覆盖

9. 局部内部类

  • 在方法中创建一个有名字的内部类,但这个内部类不能有访问说明符。(public,protected,private)

10. 内部类标识符

  • 外部类名字$内部类名字.class

继续阅读