ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

【JavaSE】【面向对象06】类的五大成员之内部类

2021-12-30 09:30:30  阅读:161  来源: 互联网

标签:部类 06 内部 静态 成员 class 面向对象 JavaSE public


类的成员之五:内部类Inner Class

1、为什么要有内部类

1.内部类场景
当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构最好使用内部类。
2.内部类特点
声明为内部类可以直接使用访问外部类的所有的成员,包括私有的.

3.源代码示例:
JRE核心类库集合的迭代器大量使用内部类;每一个集合实现类都有个迭代器内部类

2、内部类的分类

(1) 静态内部类
(2)非静态内部类:

  • 成员内部类
  • 局部内部类
  • 匿名内部类

3、成员内部类

(1)如何声明成员内部类

声明的位置:在类中方法外
格式如下:

[修饰符] class 外部类{
 	[修饰符] class 成员内部类{
 	}
 }

(2)成员内部类的特点

  • 内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号。例如:Outer$Inner.class
  • 成员内部类也是外部类的一个成员,可以使用所有权限修饰符 public,protected,default,private
  • 成员内部类还可以使用final和abstract修饰
  • 成员内部类中不可以包含静态成员
  • 成员内部类可以直接使用外部类的所有成员,包括私有的。
  • 如果成员内部类有与外部类的非静态属性重名时,可以通过“外部类名.this.属性”进行区别,如果与外部类的静态属性重名时,可以通过“外部类名.类变量”进行区别

(3)如何使用成员内部类

1.在外部类中使用成员内部类

  • 在外部类的静态成员中不能使用非静态的成员内部类
  • 在外部类的非静态成员中,直接创建内部类的对象来访问内部类的属性与方法。此时把它当做一个普通的类即可

2.在外部类的外面使用成员内部类

  • 需要外部类的对象才能创建成员内部类的对象
package com.innerclass.member;

public class TestMemberClass {

	public static void main(String[] args) {
		Outer out = new Outer();
		out.outerMethod();
		
		Outer.Inner oi = out.new Inner();
		oi.innerMethod();
		
		Outer.Inner obj = out.getInner();
		obj.innerMethod();
	}

}
class Outer{
	private int value = 5;
	public static void outerStaticMethod(){
		/*Inner in = new Inner();//错误
		in.innerMethod();*/
	}
	public void outerMethod(){
		System.out.println("外部类的方法");
		/*Inner in = new Inner();//可以
		in.innerMethod();*/
	}
	class Inner{
		public void innerMethod(){
			System.out.println("内部类的方法");
			System.out.println("内部类的方法访问外部类的私有成员:"+value);
		}
	}
	//通过外部类的某个方法返回内部类的对象
	public Inner getInner(){
		return new Inner();
	}
}

4、静态内部类

(1)如何声明静态内部类

声明的位置:在类中方法外
格式如下:

[修饰符] class 外部类{
 	[修饰符] static class 静态内部类{
 	}
 }

(2)什么时候声明静态内部类

  • 当内部类需要包含静态成员时
  • 当想要在外部类的静态成员部分使用内部类时

(3)静态内部类的特点

  • 内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号。例如:Outer$Inner.class
  • 静态内部类可以使用修饰符public,protected,default,private
  • 静态内部类还可以使用final和abstract修饰
  • 静态内部类中可以包含静态成员
  • 静态内部类可以直接使用外部类的静态成员,包括私有的。但不能使用外部类的非静态成员。
  • 静态内部类中有与外部类的静态属性重名时,如果要表示是外部类的属性,那么用“外部类名.属性”

(4)如何使用静态内部类

  • 在外部类中使用静态内部类:就和使用其他普通类一样
    • 在外部类的静态成员中
    • 在外部类的非静态成员中
  • 在外部类的外面使用成员内部类:
    • 使用静态内部类的静态成员:外部类名.静态内部类名.静态内部类的静态成员
    • 使用静态内部类的非静态成员:外部类名.静态内部类名 obj = new 外部类名.静态内部类名();
      obj.静态内部类的非静态成员
package com.innerclass.staticinner;

public class TestStaticInnerClass {

	public static void main(String[] args) {
		Outer.StaticInnerClass.innerStaticMethod();
		Outer.StaticInnerClass os = new Outer.StaticInnerClass();
		os.innerMethod();
	}

}
class Outer{
	public static void outerStaticMethod(){
		StaticInnerClass.innerStaticMethod();
		StaticInnerClass si = new StaticInnerClass();
		si.innerMethod();
	}
	public static void outerMethod(){
		StaticInnerClass.innerStaticMethod();
		StaticInnerClass si = new StaticInnerClass();
		si.innerMethod();
	}
	static class StaticInnerClass{
		public static void innerStaticMethod(){
			System.out.println("内部类的静态方法");
		}
		public void innerMethod(){
			System.out.println("内部类的非静态方法");
		}
	}
}

5、局部内部类

(1)如何声明局部内部类

声明的位置:在外部类的方法或代码块中
格式如下:

[修饰符]  class 外部类{
 	方法{
			class 局部内部类{
				}
		}
}

(2)局部内部类的特点

  • 内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件“外部类的类名$数字编号内部类名.class”。
  • 局部内部类和局部变量地位类似,不能使用public,protected,private,static这些成员修饰符,但是可以使用abstract或final
  • 局部内部类不能使用static修饰,因此也不能包含静态成员。
  • 只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方都不能使用该类,因为作用域的问题。
  • 局部内部类可以使用外部类的成员,包括私有的。但是是否可以使用外部类的非静态成员要看所在方法是否是非静态的。
  • 局部内部类可以使用外部方法的局部变量,但是必须是final的。由局部内部类和局部变量的生命周期不同所致。

(3)如何使用局部内部类

  • 只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方都不能使用该类。
  • 但是它的对象可以通过外部方法的返回值返回使用,返回值类型只能是局部内部类的父类或父接口类型。
package com.innerclass.local;

public class TestLocalInnerClass {

	public static void main(String[] args) {
		Outer out = new Outer();
		Object obj = out.outerMethod();
		System.out.println(obj);
	}

}
class Outer{
	int value = 5;
	public Object outerMethod(){
		final int localValue = 10;
		class LocalInnerClass{
			public void innerMethod(){
				System.out.println("局部内部类的方法");
				System.out.println("局部内部类的方法可以使用外部类的成员:"+value);
				System.out.println("局部内部类的方法可以使用外部类的局部变量:"+localValue);
			}
		}
		//先声明后使用
		LocalInnerClass li = new LocalInnerClass();
		li.innerMethod();
		return li;
	}
}

6、匿名内部类

(1)如何声明匿名内部类

声明的位置:任何可以创建对象的语句中
格式如下:

new 父类/父接口(){
	....
}

意思是创造一个实现(继承)了接口(父类)的类的对象。

(2)匿名内部类的特点

  • 匿名内部类是类,它编译后的字节码文件名是:外部类名$数字编号.class
  • 匿名内部类必须继承父类或实现接口
  • 匿名内部类只能有一个对象
  • 匿名内部类对象只能使用多态形式引用
  • 匿名内部类是特殊的局部内部类,局部内部类的所有限制对它都适用

(3)如何使用匿名内部类

三种使用方法:

  • 继承式
  • 接口式
  • 参数式
package com.innerclass.anonymous;

import java.util.Arrays;
import java.util.Comparator;

public class TestAnonymous {

	public static void main(String[] args) {
		//继承式
		Car car = new Car(250){
			public void run(){
				System.out.println("改进型:" + getSpeed());
			}
		};
		
		Car[] cars = new Car[3];
		cars[0] = car;
		cars[1] = new Car(120);
		cars[2] = new Car(140);
		
		for (Car c : cars) {
			c.run();
		}
		
		//接口式
		Comparator com = new Comparator() {

			@Override
			public int compare(Object o1, Object o2) {
				Car c1= (Car) o1;
				Car c2= (Car) o2;
				return c1.getSpeed() - c2.getSpeed();
			}
		};
		
		Arrays.sort(cars,com);
		
		//参数式
		Arrays.sort(cars,new Comparator() {

			@Override
			public int compare(Object o1, Object o2) {
				Car c1= (Car) o1;
				Car c2= (Car) o2;
				return c1.getSpeed() - c2.getSpeed();
			}
		});
		
		
		for (Car c : cars) {
			c.run();
		}
	}

}
class Car{
	private int speed;
	
	public Car() {
		super();
	}

	public Car(int speed) {
		super();
		this.speed = speed;
	}

	public int getSpeed() {
		return speed;
	}

	public void setSpeed(int speed) {
		this.speed = speed;
	}

	public void run(){
		System.out.println("标准发动机助跑" + speed);
	}
}

标签:部类,06,内部,静态,成员,class,面向对象,JavaSE,public
来源: https://blog.csdn.net/weixin_43589563/article/details/122229156

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有