java基础之内部类

       学习了Java内部类,今天写一下学习后的一些收获,欢迎交流指正。
       内部类简单的来说就是在一个类内再定义一个类,这个类的权限修饰符被扩展了,正常的外部类不可以使用private修饰符,但对于内部类来说可以使用。一个内部类可以如下简单定义:

class OutClass{
	class InnerClass{
		public void inner(){
			System.out.println("im inner class");
		}
	}
}

InnerClass 即是OutClass的内部类。想要生成一个非静态内部类的对象,必须生成内部类的封装类(即外部类)的对象,然后用封装类的对象再new 出一个内部类,具体例子如下
OutClass oc=new OutClass();
oc.new InnerClass();
在外部类可以引用内部类的同时,java的内部机制会自动将你的外部类的对象引用给内部类,说的简单点就是内部类可以使用外部类的一切成员变量以及方法,不论其修饰符权限,尽管他的修饰符是private,内部类依旧可以调用。内部类除了可以简单定义在一个单纯的类内,他还可以定义在封装类的方法内或者一些作用域内如if语句等,如果内部类定义在方法或者作用域内,则表明除了再这个作用域内可以进行内部类的构建,其他地方进行构建就会出现错误。但是如果作用域内生成了内部类的对象并且作为返回值跳出作用域的话,那么这个内部类的对象是合法的。
       内部类可以分为静态内部类,非静态内部类和匿名内部类
       1.静态内部类
       顾名思义,静态内部类就是使用静态修饰符static修饰的内部类。静态内部类有如下的几个特点。第一:静态内部类的调用不再需要用封装类的对象进行调用了,还是用上面的代码进行举例:如果上面的内部类InnerClass类定义成static class InnerClass的话,我们调用就可以使用这个格式 OutClass.InnerClass.inner(); 并不需要先new 一个外部类的对象了。
第二:静态内部类有自己的局限性,即如果内部类是静态的话,内部类只能调用外部类静态的成员变量以及静态的方法。
第三:一个非静态的内部类中除非用final修饰符修饰成员变量可以定义静态成员变量外,不可以定义静态成员变量和静态方法,如果要定义,则内部类必须是静态内部类。
       2.非静态内部类
       这种内部类就是普通的内部类,没什么需要进行特殊分析的。
       3.匿名内部类
       顾名思义可以知道匿名内部类就是没有类名的内部类,有的人会疑惑怎么定义一个没有类名的匿名内部类。具体事例如下:

public class Parce{
	public Contents cont(){
		return new Contents(){
			private int i=11;
			public int value(){
				return i;
			}
		};
	}
}

我们可以看到return 后面跟了一个new Contents(){

}
这是什么意思呢,这个表达的就是我有一个不知名的类继承于Contends类,我这个类的成员变量和方法都在后面的大括号里定义了。匿名内部类和普通的内部类又有所不同了,匿名内部类里如果要使用匿名内部类外定义的一个对象,就必须将外部对象用final修饰符进行修饰,这样对于编译器来说就是合法的。

       对于内部类来说,内部类是可以继承别的类或者进行接口的实现的,可以如下进行定义

abstract class InnerClassFather{
	public void fatherSay();
}

public interface InnerInterface{
	public void interfaceSay();
}

class OutClass{
	public void outClassSay(){
		System.out.println("I'm outclass");
	}
	class InnerClassSon extends InnerClassFather{
		public void fatherSay(){
			System.out.println("I'm InnerClassSon");
		}
	}

	class InnerClassInterface implement InnerInterface{
		public void interfaceSay(){
			System.out.println("I'm InnerInterface");
		}
	}
}

       内部类除了可以继承别的类,内部类的本身也是可以被继承的。但是对于内部类来说,继承是一件麻烦的事情,因为内部类的对象和封装类的对象是联系在一起的,内部类拥有封装类对象的引用,但是在继承内部类时,子类会丢失内部类对封装类的引用,所以我们会用一个构造器将对象引用给继承子类。

class OutClass{
		class InnerClass{
			public void say(){
				System.out.println("I'm InnerClass");
			}
		}
}

class InnerClassSon extends OutClass.InnerClass{
		InnerClassSon (OutClass oc){
			oc.super();
		}
}

       既然内部类可以被继承,也就可以联想到内部类行为其实也是可以覆盖的。不过注意的是内部类的覆盖只发生在内部类的层面之上。所以需要外部类实现继承,内部类也实现继承。例子如下:

class OutClass{
		class InnerClass{
			public void say(){
				System.out.println("I'm InnerClass");
			}
		}
}

class OutClassSon extends OutClass{
		class InnerClassSon extends OutClass.InnerClass{
				public void say(){
					System.out.println("I'm InnerClassSon ");
				}
		}

		public static void main(String[] args){
			OutClassSon oc=new OutClassSon();
			oc.new InnerClassSon().say();
		}
}

注意,上溯造型对于继承的内部类来说不具有实际意义。意思就是如果我们把上的 OutClassSon oc=new OutClassSon(); oc.new InnerClassSon().say();
修改成 OutClass oc=new OutClassSon(); oc.new InnerClassSon().say();
虽然OutClass oc是对OutClassSon的上溯造型,但是oc并不具有对继承子类构造器使用权限。
       对于内部类就写到这边,其他的还要多多学习后才可以写出来,如果我写的地方有错误之处,希望大家帮我多多指正。

你可能感兴趣的:(java,内部类,java基础之内部类,内部类,java,java基础)