java面向对象22_内部类

1.内部类概念

  • 什么是内部类?

    将类写在其它类的内部,可以写在其他类的成员位置和局部位置,这时写在其他类内部的类就称为内部类(内置类,嵌套类),其他类也称为外部类。

  • 什么时候使用内部类?

    在描述事物时,若一个事物内部还包含其它可能包含的事物,比如在描述汽车时,汽车中还包含这发动机,这时发动机就可以使用内部类来描述。

  • 内部类的分类有哪些?

​ 内部类分为:成员内部类、局部内部类、匿名内部类和静态内部类。

  • 内部类的编译特点?

    对于一个名为OuterClass的外部类和一个名为InnerClass的内部类,在编译成功后,会出现这样两个class文件:OuterClass.class和OuterClass$InnerClass.class。

  • 内部类的访问特点?

    内部类可以直接访问外部类中的成员,外部类要访问内部类,必须要建立内部类对象。

2.成员内部类

成员内部类,定义在外部类中的成员位置。与类中的成员变量相似,可通过外部类对象进行访问。

  • 定义格式
class 外部类 {
	修饰符 class 内部类 {
		// 其它代码
	}
}

【示例】成员内部类代码演示

// 外部类
class OuterClass {
	// 成员内部类
	public class InnerClass {
		// 成员内部类的成员变量
		String name;
	    // 成员内部类的构造方法
		public InnerClass() {} // 无参构造方法
		public InnerClass(String name) { // 有参构造方法
			this.name = name;
		}		
		// 成员内部类的成员方法
		public void test() {
			System.out.println("innerClass test()");
		}
	}
	// 外部类成员方法
	public void show() {
		// 实例化成员内部类
		InnerClass in = new InnerClass("小明");
		// 获取成员内内部类的属性
		System.out.println(in.name); // 输出:小明
		// 调用成员内内部类的方法
		in.test();
	}
}
// 测试类
public class InnerClassDemo {
	public static void main(String[] args) {
		new OuterClass().show();
	}
}
  • 内部类访问方式

外部类名.内部类名 变量名 = new 外部类名(实参列表).new 内部类名(实参列表);

【示例】内部类访问方式代码演示

// 外部类
class OuterClass {
	String sex = "娜娜";
	// 成员内部类
	public class InnerClass {
		// 成员内部类的成员变量
		String name;
	    // 成员内部类的构造方法
		public InnerClass() {} // 无参构造方法
		public InnerClass(String name) { // 有参构造方法
			this.name = name;
		}
		// 成员内部类的成员方法
		public void test() {
			System.out.println("innerClass test()");
		}
	}
}
// 测试类
public class InnerClassDemo {
	public static void main(String[] args) {
		/* 
		 * 实例化内部类完整写法
		 * OuterClass outer = new OuterClass();
		 * OuterClass.InnerClass in = outer.new InnerClass();
		 */
		OuterClass.InnerClass in = new OuterClass().new InnerClass("小明"); 
		// 获取成员内内部类的属性
		System.out.println(in.name); // 输出:小明
		// 调用成员内内部类的方法
		in.test();
	}
}
  • 成员内部类注意点
  1. 外部类的静态方法中不能访问成员内部变量。

  2. 成员内部类中不能存在任何的静态变量和静态方法。

  3. 成员内部类是依附于外围类的,所以只有先创建了外围类才能够创建内部类。

  4. 访问外部类成员变量:外部类.this.成员变量,访问外部类成员方法:外部类.this.成员方法。

【示例】成员内部类注意点代码演示

// 外部类
class OuterClass {
	String name = "娜娜";
	// 成员内部类
	public class InnerClass {
		// 成员内部类的成员变量
		String name;
	    // 成员内部类的构造方法
		public InnerClass() {} // 无参构造方法
		public InnerClass(String name) { // 有参构造方法
			this.name = name;
		}
		// 成员内部类的成员方法
		public void show(String name) {
			// 局部变量,成员内部类成员变量,外部类成员变量同名时的访问
			System.out.println("局部变量:" + name);
			System.out.println("成员内部类成员变量:" + this.name);
			System.out.println("外部类成员变量:" + OuterClass.this.name);
		}
		// 2、成员内部类中不能存在任何的静态变量和静态方法。
		// static String company = "北京尚学堂"; 编译错误
		// public static test() {} 编译错误
		
	}
	// 外部类的静态方法
	public static void show() {
		// 1、外部类的静态方法中不能访问成员内部变量。
		// InnerClass in = new InnerClass(); 编译错误
	}
}
// 测试类
public class InnerClassDemo {
	public static void main(String[] args) {
		OuterClass.InnerClass in = new OuterClass().new InnerClass("小明"); 
		// 获取成员内内部类的属性
		System.out.println(in.name); // 输出:小花
		// 调用成员内内部类的方法
		in.show("小花");
	}
}

3.局部内部类

局部内部类,定义在外部类方法中的局部位置。与访问方法中的局部变量相似,可通过调用方法进行访问

  • 定义格式
class 外部类 {
	修饰符 返回值类型 方法名(参数列表) {
		class 内部类 {
			// 其他代码
		}
	}
}

【示例】局部内部类代码演示

// 外部类
class OuterClass {
	// 外部类的方法
	public void test() {
		// 局部内部类
		class InnerClass {
			// 局部内部类的成员变量
			public String name;
		    // 局部内部类的构造方法
			public InnerClass() {} // 无参构造方法
			public InnerClass(String name) { // 有参构造方法
				this.name = name;
			}
			// 局部内部类的成员方法
			public void show() {
				System.out.println("局部内部类中的show方法");
			}
		}
		
		// 实例化局部内部类,注意只能在对应的局部作用域中实例化!!!
		InnerClass in = new InnerClass("小明");
		// 获取局部内部类中的成员变量
		System.out.println("name:" + in.name);
		// 调用局部内部类中的成员方法
		in.show();
	}
}
  • 局部内部类注意点
  1. 局部内部类只能在对应的局部作用域中实例化。

  2. 局部内部类中不能存在任何的静态变量和静态方法。

  3. 局部内部类是依附于外围类的,所以只有先创建了外围类才能够创建内部类。

  4. 访问外部类成员变量:外部类.this.成员变量,访问外部类成员方法:外部类.this.成员方法。

  5. 局部内部类访问的外部局部变量都必须用 final修饰,以防止更改外部局部变量的值。JDK1.8之后不必添加final。

【示例】局部内部类注意点代码演示

// 外部类
class OuterClass {
	String name = "娜娜";
	// 外部类的方法
	public void test() {
		// 4.如果局部内部类要访问外部局部变量,那么需要用final来修饰该外部局部变量。
		final int num = 18; // JDK1.8之后可以省略final
		// 局部内部类
		class InnerClass {
			// 局部内部类的成员变量
			public String name;
		    // 局部内部类的构造方法
			public InnerClass() {} // 无参构造方法
			public InnerClass(String name) { // 有参构造方法
				this.name = name;
			}
			// 局部内部类的成员方法
			public void show(String name) {
				// 3.局部变量,局部内部类成员变量,外部类成员变量同名时的访问
				System.out.println("局部变量:" + name);
				System.out.println("成员内部类成员变量:" + this.name);
				System.out.println("外部类成员变量:" + OuterClass.this.name);
				// 访问外部局部变量
				System.out.println("外部局部变量:" + num);
			}
			// 2、成员内部类中不能存在任何的静态变量和静态方法。
			// static String company = "北京尚学堂"; 编译错误
			// public static test() {} 编译错误
		}
		
		// 1、局部内部类只能在对应的局部作用域中实例化。
		InnerClass in = new InnerClass("小明");
		// 获取局部内部类中的成员变量
		System.out.println("name:" + in.name);
		// 调用局部内部类中的成员方法
		in.show("小花");
	}
}
// 测试类
public class InnerClassDemo2 {
	public static void main(String[] args) {
		new OuterClass().test();
	}
}

4.匿名内部类

匿名内部类也就是没有名字的内部类,它是局部内部类的一种。

使用匿名内部类前提是必须继承一个父类或实现一个接口,是创建某个类型子类对象的快捷方式。

  • 定义格式
class 外部类 {
	public 返回值类型 方法名(参数列表) {
		new 接口() | 父类构造器(参数列表) {
			// 其他代码
		}
	}
}

【示例】不使用匿名内部类案例

// 父类或一个接口,用于局部内部类继承或实现
abstract class Parent {
	abstract void show1();
	abstract void show2();
}
// 外部类
class OuterClass {
	public void test() {
		// 局部内部类
		class InnerClass extends Parent {
			@Override
			void show1() {
				System.out.println("内部类中的show1方法");
			}
			@Override
			void show2() {
				System.out.println("内部类中的show2方法");
			}
		}
		// 局部内部类实例化。
		InnerClass in = new InnerClass();
		in.show1();
		in.show2();
	}
}

使用匿名对象的方式,将定义子类(包含继承父类或实现接口)与创建子类对象两个步骤由一个格式一次完成。虽然是两个步骤,但是两个步骤是连在一起完成的。

【示例】匿名内部类使用案例

// 父类或一个接口,用于匿名内部类继承或实现
abstract class Parent {
	abstract void show1();
	abstract void show2();
}
// 外部类
class OuterClass {
	public void test() {
		// 匿名内部类
		Parent p = new Parent() {
			@Override
			void show1() {
				System.out.println("匿名内部类中的show1方法");
			}
			@Override
			void show2() {
				System.out.println("匿名内部类中的show2方法");
			}
		};
		p.show1();
		p.show2();
	}
}

匿名内部类如果不定义变量引用,则也是匿名对象。

  • 匿名内部类注意点
  1. 匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内部类生效。

  2. 匿名内部类中是不能定义构造函数的,由构造代码块完成初始化工作。

  3. 匿名内部类中慎重添加特有的成员变量和成员方法,因为不方便使用!

5.静态内部类

关键字static可以修饰成员变量、方法、代码块,static还可以修饰内部类,使用static修饰的内部类我们称之为静态内部类。

【示例】静态内部类案例

// 外部类
class OuterClass {
	// 静态内部类,用static来修饰
	public static class InnerClass {
		// 静态内部类的成员变量
		String name;
	    // 静态内部类的构造方法
		public InnerClass() {} // 无参构造方法
		public InnerClass(String name) { // 有参构造方法
			this.name = name;
		}
		// 静态内部类的成员方法
		public void show() {
			System.out.println("静态内部类的show方法");
		}
	}
	// 外部类静态方法
	public static void test() {
		// 初始化静态内部类
		InnerClass inner = new InnerClass("小明");
		// 获取静态内部类中的成员变量
		System.out.println("name:" + inner.name);
		// 调用静态内部类中的成员方法
		inner.show();
	}
}
  • 静态类访问方式

外部类名.静态内部类名 变量名 = new 外部类名.静态内部类名(形参列表);

【示例】静态类访问方式代码演示

// 外部类
class OuterClass {
	// 静态内部类,用static来修饰
	public static class InnerClass {
		// 静态内部类的成员变量
		String name;
	    // 静态内部类的构造方法
		public InnerClass() {} // 无参构造方法
		public InnerClass(String name) { // 有参构造方法
			this.name = name;
		}
		// 静态内部类的成员方法
		public void show() {
			System.out.println("静态内部类的show方法");
		}
	}
}
// 测试类
public class InnerClassDemo4 {
	public static void main(String[] args) {
		// 创建静态内部类
		OuterClass.InnerClass inner = new OuterClass.InnerClass("小明");
		// 获取静态内部类中的成员变量
		System.out.println("name:" + inner.name);
		// 调用静态内部类中的成员方法
		inner.show();
	}
}
  • 静态内部类注意点
  1. 静态内部类的创建不需要依赖外部类。

  2. 静态内部类不能使用外部类的非static成员变量和方法。

  3. 如果内部类中定义了静态成员,那么该内部类也必须是静态的。

  • 调用静态内部类是静态变量和静态方法
  1. 调用静态变量:OuterClass.InnerClass.staticVariable

  2. 调用静态方法:OuterClass.InnerClass.staticFunction();

ps:如需最新的免费文档资料和教学视频,请添加QQ群(627407545)领取。

发布了55 篇原创文章 · 获赞 0 · 访问量 785

猜你喜欢

转载自blog.csdn.net/zhoujunfeng121/article/details/104619480