Java内部类

概述

  • 内部类信息(属性、方法)可以和外部类重名;
  • 内部类是具有类的基本特征的独立实体;
  • 可以利用访问修饰符隐藏内部类的实施细节,提供了更好的封装;
  • 静态内部类使用时可直接使用,不需先创造外部类。
  • 内部类可以用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独立。
  • 内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体。
  • 内部类提供了更好的封装,除了该外围类,其他类都不能访问。
  • 创建内部类对象的时刻并不依赖于外围类对象的创建。

成员内部类

  • 作为成员存在,可以被任意权限修饰符修饰
  • 可以调用外部所有信息
  • 外部类使用,new对象打点
  • 其他类使用:外部类.内部类 内部对象 = 外部对象.new 内部类() OuterTest2 out = new OuterTest2(); OuterTest2.Inner inner = out.new Inner();先new外部类,在new内部类,最后打点使用 也可:外部类.内部类 变量名 = new 外部类().new 内部类();
  • 可以和外部类属性、方法重名,调用时外部类名this属性/方法即可
  • 有类的基本特征
public class Outertest1 {
	private int num = 100;
	
	public Outertest1() {
		System.out.println("OuterTest1构造函数");
	}
	public class Inner1{
		private int num = 200;
		
		public Inner1() {
			System.out.println("Inner1构造函数");
		}
		
		public void test() {
			//可以直接调用外部类私有成员
			System.out.println("OuterTest1的n"+Outertest1.this.num);
			System.out.println("Inner1的n"+num);
			System.out.println(string);//外部类不重名变量
		}
	}
	
	public static void main(String[] args) {
		Outertest1 n = new Outertest1();
		Inner1 n1 = n.new Inner1();//使用外部类对象创建内部类对象
		
		System.out.println("OuterTest1的n"+n.num);
		System.out.println("Inner1的n"+n1.num);
		
		n1.test();
		System.out.println("--------");
		
		n.outer();
		
//		OuterTest1构造函数
//		Inner1构造函数
//		OuterTest1的n100
//		Inner1的n200
//		OuterTest1的n100
//		Inner1的n200
		
		//要先new 外部类,然后 new 内部类
//		Inner1 n2 = new Inner1();
	}
	
	public void outer() {
		Inner1 n3 = new Inner1();//直接调用内部类
		n3.test();
	}
//	Inner1构造函数
//	OuterTest1的n100
//	Inner1的n200
}

注意:main方法中不能new 内部类,但是外部类中的方法可以直接new 内部类

  • 首先你的内部类不是静态的对吧(不是static class)
  • 而main方法是静态的
  • main 方法是个静态方法,而 静态 类不是个静态内部类,所以不能直接初始化
  • 对main方法而言,虽然写在类中,它是游离于任何类之外的(就跟C++一样,单独一个main方法),因此某类的非静态内部类对它而言是不直接可见的,也就无法直接访问

内部类可以调用成员方法,静态方法

public class OuterTest2 {
	private static int OuterStaicInt = 12;

	//成员方法
	public void OuterMathod() {
		System.out.println("Outer的成员方法");
	}
	//静态方法
	public static void OuterStaticMathod() {
		System.out.println("Outer的静态方法");
	}
	
	public class Inner {

		//方法才能调用方法,而System.out.println(x); 是一个内置方法,所以只能放到方法里去调用,不能写在类里.
		//System.out.println("OuterStaticInt: "+OuterStaicInt);
		
		public void InnerMathod() {
			//访问外部类静态变量
			System.out.println("OuterStaticInt: "+OuterStaicInt);
			OuterMathod();
			OuterStaticMathod();
		}
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		OuterTest2 out = new OuterTest2();
		OuterTest2.Inner inner = out.new Inner();
		inner.InnerMathod();
	}

}

注意:方法才能调用方法,而System.out.println(x); 是一个内置方法,所以只能放到方法里去调用,不能写在类里.

静态内部类

  • 作为静态成员属性存在,可以被任意权限修饰符修饰
  • 只可以调用外部static相关联的信息
  • 外部类使用时,类名信息即可
  • 其他类使用时,OuterInner inner=new OuterInner;然后打点调用成员信息。静态信息,直接使用OuterInner信息
public class OuterTest3 {
	private static String staticString = "外部类静态变量staticString";
	private String string = "外部变量";
	private static String outerStaticString = "外部静态变量outerStaticString";

	private static void OuterStaticMathod() {
		System.out.println("outer中的静态方法");
	}

	private void OuterMathod() {
		System.out.println("outer中的方法");
	}
	
	public static class Inner{
		private static String staticString = "内部类静态变量staticString";
		
		public void Test() {
//			System.out.println(string);//外部类中变量非静态,不能用,报错,非静态类可直接调用
			System.out.println(new OuterTest3().string);//外部变量
			//内部类中没有重名变量,可直接调变量
			System.out.println(outerStaticString);//外部静态变量outerStaticString
			//静态类中调用重名静态变量:类.静态变量,非静态类调用重名变量需要:类.this.变量
			System.out.println(OuterTest3.staticString);//外部类静态变量staticString
			System.out.println(staticString);//内部类静态变量staticString
			OuterStaticMathod();//outer中的静态方法
//			OuterMathod();//外部类中方法非静态,不能调用,报错
			
		}
		public static void StaticTest() {
			OuterStaticMathod();
		}
		
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//静态内部类使用时与内部成员类不同
		//OuterTest3.Inner inner = new OuterTest3().new Inner();
		OuterTest3.Inner inner = new Inner();
		//或
//		OuterTest3 outer = new OuterTest3();
//		OuterTest3.Inner inner = new Inner();
		inner.Test();
//		OuterTest3.Inner.Test();//非静态方法不可以这样
		OuterTest3.Inner.StaticTest();
		
		outer();
	}
	
	public static void outer() {
//		Inner.Test();//不能调用非静态方法
		System.out.println(OuterTest3.Inner.staticString);
		Inner.StaticTest();
	}

//	外部变量
//	外部静态变量outerStaticString
//	外部类静态变量staticString
//	内部类静态变量staticString
//	outer中的静态方法
//	outer中的静态方法
//	内部类静态变量staticString
//	outer中的静态方法


}

注意:

  • 静态内部类不能直接访问外部类的非静态成员,但,可以通过new 外部类().成员的方式访问
  • 如果外部类的静态成员与内部类的静态成员相同, 可以通过"类名.静态成员"来访问外部类的静态成员;如果不同,可以直接调用外部类的静态成员名。
  • 创建静态内部类的对象时,不需要外部类的对象,可以直接创建;
  • 利用 外部类.内部类 引用=new 外部类.内部类(); 然后利用引用.成员信息(属性、方法)调用。OuterTest3.Inner inner = new Inner();
  • 访问内部类的静态信息,直接外部类.内部类.静态信息就可以了。OuterTest3.Inner.StaticTest();方法,变量都可访问

局部内部类

  • 存在于方法之中,只能在方法中使用,具备类的基本特征,类前不能有访问权限
  • 无法创造静态信息,因为在方法结束后,内存需要释放
  • 可以直接访问方法的局部变量,但是无法修改。
  • 可以随意访问外部的所有信息

匿名内部类

如果接口的实现类(或者是父类的子类)只需要使用唯一的一次,那么这种情况下就可以省略掉该类的定义,而改为使用匿名内部类

匿名内部类的定义格式:
接口名称 对象名 = new 接口名称() {
    // 覆盖重写所有抽象方法
};

  • new代表创建对象的动作
  • 接口名称就是匿名内部类需要实现哪个接口
  • {…}这才是匿名内部类的内容
public interface MyInterface {
	void Mathod();
}
public class MyInterfaceImpl implements MyInterface {

	@Override
	public void Mathod() {
		// TODO Auto-generated method stub
		System.out.println("接口中Mathad");
	}

}
public class Test {
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyInterface m = new MyInterfaceImpl();//实现类
		m.Mathod();
		
		//匿名类可不写MyInterfaceImpl直接实现
		MyInterface m2 = new MyInterface() {//不用实现类,只用到一次
			@Override
			public void Mathod() {
				// TODO Auto-generated method stub
				System.out.println("匿名内部类中Mathod");
			}
		};
		m2.Mathod();//对象为m2
		
		
		new MyInterface() {
			@Override
			public void Mathod() {
				System.out.println("匿名对象匿名类中的Mathod");
			}
		}.Mathod();//匿名对象
	}

}

例2:

public interface Animal {
	public void speak();
}

public class OuterTest {
	
	public static Animal getInnerInstance(String speak) {
		
		return new Animal() {
			@Override
            public void speak(){
                System.out.println(speak);
            }
		};
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		getInnerInstance("aaa").speak();
	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值