内部类的定义:
内部类:定义在类内部的类,在广义上可以分为:成员内部类、局部内部类,匿名内部类,静态内部类四种。
成员内部类:
定义:定义在类内部,方法外部的类。
含有内部类的成员内部类在编译的时候会产生两个class文件(外部类.class、外部类$内部类 .class)原因是成员内部类依赖于
外部类,内部类当你需要调用内部类的时候,需要先创建外部类。而编译器会默认为成员内部类添加了一个指向外部类对象的
引用,来提供内部类被访问。
成员内部类注意事项:
1.成员内部类中不能定义静态方法;
2.如果将成员内部类中定义抽象方法,则该成员内部类必须是一个抽象类;
3.成员内部类可以继承其他的外部类,并且可以进行多态;
4.成员内部类也可以直接去实现接口,并且也可以通过接口进行多态;
5.在定义内部类的外部类方法中可以直接对成员内部类进行实例化操作;
6.当成员内部类拥有和外部类同名的成员变量或者方法时,默认情况下访问的是成员内部类的成员。
注意事项示例:
public class MyOuterClassDemo1 {
String outValue="this is outValue";
如果将成员内部类中定义抽象方法,则该成员内部类必须是一个抽象类
abstract class MyInnerClass{
String innerValue = "this is inner Values";
public void testInner() {
System.out.println("this is inner Mathod");
}
public abstract void eat();
}
class MyInnerClass{
String innerValue = "this is inner Values";
public void testInner() {
System.out.println("this is inner Mathod");
}
}
/**
* 成员内部类可以继承其他的外部类,并且可以进行多态
* MyOuterClassDemo1 myouter = new MyOuterClassDemo1();
SuperClass myinner = myouter.new MyInnerClass();
myinner.superMethod();
*/
class MyInnerClass extends SuperClass{
String innerValue = "this is inner Values";
public void testInner() {
System.out.println("this is inner Mathod");
}
}
public class MyInnerClass extends MyOuterClassDemo1{
String innerValue = "this is inner Values";
public void testInner() {
System.out.println("this is inner Mathod");
}
}
public static void run() {
System.out.println("this is out static Method");
}
public void test() {
// 在定义内部类的外部类方法中可以直接对成员内部类进行实例化操作
MyInnerClass myinner = new MyInnerClass();
}
}
静态内部类:
定义:用static修饰的成员内部类
静态内部类注意事项:
1.在静态内部类中不能访问外部类的非静态方法和成员变量;
2.在外部类中可以直接实例化静态内部类;
3.在其他类中则通过外部类.内部类的方式创建一个静态内部类对象;
4.在静态内部类里面可以定义普通方法。
5.在外部类里面可以直接实例化静态内部类。在其他外部类实例化语法:
外部类明.内部类 对象名=new 外部类.内部类构造方法。
注意事项示例:
public class MyOuterClassStatic {
String outerStr="tomcat";
static class MyStaticinnerClass{
String inValue;
public void testInner(){
System.out.println("this is testInner() ");
// 在静态内部类中不能访问外部类的非静态方法和成员变量
// System.out.println(outerStr);
}
public static void sleep() {
int i=10;
}
}
public void testOuter(){
System.out.println("this is testOuter!");
// 在外部类中可以直接实例化静态内部类
MyStaticinnerClass inner = new MyStaticinnerClass();
inner.testInner();
// 在其他类中则通过外部类.内部类的方式创建一个静态内部类对象
MyOuterClassStatic.MyStaticinnerClass classStatic = new MyOuterClassStatic.MyStaticinnerClass();
}
}
匿名内部类
注意事项:
1.可以通过多态来进行多次调用,但是只能调用重写接口的方法,不是重写的方法则无法调用;
2. 可以通过直接new接口的方式直接创建一个默认实现该接口的一个匿名内部类;
3. 匿名内部类不能有访问修饰符和static修饰符;
4.匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写;
5.通过抽象类里面有构造方法,通过接口则没有构造方法。
注意事项示例:
interface TestInterface{
public void m1();
}
abstract class abClass{
abstract void m3();
}
public class NoNameOuterClass implements TestInterface{
public void outTest() {
// 可以通过直接new接口的方式直接创建一个默认实现该接口的一个匿名内部类
TestInterface t=new TestInterface() {
@Override
public void m1() {
System.out.println("this is inner method");
}
public void m2() {
}
};
t.m1();
// 匿名内部类可以通过多态来进行多次调用,但是只能调用重写接口的方法,不是重写的方法则无法调用
// t.m2();
abClass ab = new abClass() {
@Override
void m3() {
// TODO Auto-generated method stub
}
};
ab.m3();
}
public void test() {
TestInterface t = new NoNameOuterClass();
t.m1();
}
@Override
public void m1() {
// TODO Auto-generated method stub
}
}
局部内部类
定义:在方法内部的类被称为局部内部类
注意事项:
1.局部内部在访问局部变量时,局部变量必须声明成final;
2.局部内部类不能继承其外部类,也不能实现接口;
3.当访问内部和外部类重名的成员时,访问的是内部类的实例变量,因为重名时,内部类的成员优先级更高;
4. 如果想明确的使用外部类的this,那么就必须在this之前加上外部类的类名;
5.在局部内部类中可以通过外部类的类名和外部类对象调用外部类的静态成员(静态变量,静态方法);
6.可以在同一方法的不同局部内部类中的方法相互调用(因为作用域相同)。
public class OuterClass {
private String instanceStr = "外部类的实例变量";
private static String staticStr = "外部类的静态变量";
public void testInner() {
int i=10;//默认为final
class Inner{
private String instanceStr = "内部类的实例变量";
public void innerPrint() {
// 访问的是内部类的实例变量
System.out.println(this.instanceStr);
// 如果想明确的使用外部类的this
// 那么就必须在this之前加上外部类的类名
System.out.println(OuterClass.this.instanceStr);
System.out.println(staticStr);
// 在局部内部类中可以通过外部类的类名和外部类对象调用外部类的静态成员(静态变量,静态方法)
System.out.println(OuterClass.staticStr);
System.out.println(staticStr);
OuterClass.run();
// i=12;
System.out.println(i);
}
}
Inner inner = new Inner();
inner.innerPrint();
System.out.println(inner.instanceStr);
class Inner1{
public void innerMethod() {
// 可以在同一方法的不同局部内部类中的方法相互调用
Inner in = new Inner();
in.innerPrint();
}
}
}
public static void run() {
}
public static void main(String[] args) {
OuterClass outer = new OuterClass();
outer.testInner();
}
}