内部类总结

在说内部类之前提一下成员方法、静态方法、普通方法。因为内部类和成员方法很相似

成员方法:成员方法不能存在静态变量,成员方法可以访问静态变量。

静态方法:静态方法可以存在静态变量,静态方法不能访问普通变量。

静态方法不能访问类中普通属性(静态方法没有对象产生,普通属性和对象有关),但是静态方法可以访问静态属性

普通方法可以访问类中静态属性,但是普通方法可访问类中普通属性

 

内部类

定义:在一个类中进行其他类结构的嵌套。

      内部类的优点:

     (1)、内部类和外部类可以相互访问彼此的私有域。

     (2)、内部类可以实现java的单继承局限。

     (3)、内部类可以对同一包中的其他类隐藏起来,仅供外部类使用(保护性)

      内部类的缺点: 结构复杂

内部类分类:

1、普通内部类(在类内部): 看代码

class Outter {
	private String msg1 = "外部类的私有域";

	// ----------------------------------
	// 内部类
	class Inner {
		public void fun() {
			System.out.println(msg1);
		}
	}
	// ----------------------------------

	// 普通外部类
	public void test() {
		Inner in = new Inner(); // 声明并实例化一个内部类
		in.fun(); // 调用内部类的而普通方法
	}
}

public class Test {
	public static void main(String[] args) {
		Outter out = new Outter();
		out.test();
	}
}

总结:在内部类中调用成员变量与成员方法类似:成员方法调用类中的成员变量,直接调用(没有对象),内部类也是一样的,直接调用。

 

1.1 普通内部类(在外部调用内部类): 看代码

class Outter {
	private String msg = "外部类的私有域";

	// 扩展一个get方法,方便外部类调用
	public String getMsg() {
		return msg;
	}

	// 普通外部类
	public void test() { // 2
		// this表示当前对象
		Inner in = new Inner(this); // 3 // 声明并实例化一个内部类
		in.fun(); // 5 // 调用内部类的而普通方法
	}
}

// 内部类

// // 因为主类的属性是封装起来的,要在外部调用,需要使用get方法。
class Inner {
	private Outter out; // Inner类中的外部对象

	public Inner(Outter out) { // 4
		this.out = out; // 通过构造方法传入out对象
	}

	public void fun() { // 6
		System.out.println(out.getMsg()); // 此处调用msg需要对象来调用,所以Inner中要有一个外部类的对象
	}
}

public class Test{
	public static void main(String[] args) {
		Outter out = new Outter(); // 1
		out.test(); // 2
	}
}

 

1.3  内部类实现多继承:java不允许多继承,但是内部类可以。

class A {
	private String msg = " A 的属性";

	public String getMsg() {
		return msg;
	}
}

class B {
	private String age = " B 的属性";

	public String getAge() {
		return age;
	}
}

class C {
	// 在C的内部,继承了A和B
	// ---------------------------------------
	class InnerclassA extends A {
		public String name() {
			return super.getMsg(); // 通过super访问父类同名的方法
		}
	}

	class InnerclassB extends B {
		public String age() {
			return super.getAge();
		}
	}
	// --------------------------------------

	// 外部类
	public String name() {
		// 在外部类中声明方法,调用内部类
		return new InnerclassA().name();
	}

	public String age() {
		return new InnerclassB().age();
	}
}

public class Test{
	public static void main(String[] args) {
		C c = new C();
		System.out.println(c.name());
		System.out.println(c.age());
	}
}

 

2、内部类与外部类的关系:(在外部类之外)

     (1)、对于非静态内部类而言,内部类的创建需要依赖于外部类的实例化对象,在没有外部类之前是无法创建内部类的。

     (2)、内部类是一个相对独立的个体,与外部类不是is-a关系。

     (3)、内部类可以直接访问外部类的元素(包含私有域),外部类不可以直接访问内部类元素,需要通过内部类的引用间接访问。

 

   2.1     内部类直接访问外部元素,外部类引用访问内部类

class Outter {
	private String msg1 = "外部类的私有域";

	// 普通内部类
	class Inner {
		// 内部类的私有域
		private String msg2 = "内部类的私有域";

		public void fun() {
			System.out.println(msg1);// 普通内部类调用外部类的方法
		}
	}

	// 普通外部类
	public void test() {
		// 外部类不能直接调用内部类,需要通过对象引用间接调用
		Inner in = new Inner();
		in.fun(); // 外部类调用内部类方法
		System.out.println(in.msg2); // 外部类调用内部类私有域
	}
}

public class Test{
	public static void main(String[] args) {
		Outter out = new Outter();
		out.test();
	}
}

 

3、创建内部类的语法(在外部类之外):

      (1)、创建非静态内部类(普通内部类)的语法:

             外部类.内部类 内部类对象引用 = new 外部类().new内部类();

          eg:   Outter.Inner in = new Outter().new Inner();

 

      (2)、创建静态内部类语法:

             外部类.内部类 内部类对象引用 = new 外部类.内部类();

          eg:   Outter.Inner in = new Outter.Inner();

代码示例:

      (1)创建非静态内部类语法:

class Outter {
	private String msg1 = "外部类的私有域";

	// 普通内部类
	class Inner {
		public void fun() {
			System.out.println(msg1);// 普通内部类调用外部类的方法
		}
	}

}

public class Test{
	public static void main(String[] args) {
		// 创建Inner对象
		Outter.Inner in = new Outter().new Inner();
		in.fun();
	}
}

      (2)创建静态内部类的语法:

class Outter {
	private static String msg = "外部类的私有域";

	// 静态内部类
	static class Inner {
		public void fun() {
			System.out.println(msg);// 普通内部类调用外部类的方法
		}
	}

}

public class Test{
	public static void main(String[] args) {
		// 直接产生内部类,没有外部类产生
		Outter.Inner in = new Outter.Inner(); // -----------------》语法
		in.fun();
	}
}

 

4、内部类的分类:

    (1)、成员内部类-成员方法

           1)、成员内部类不能存在任何static变量或方法,可以访问外部静态域。

           2)、成员内部类需要依附外部类new Outter.new Inner();

           3)、内部类可以使用private封装,表示私有内部类,该内部类仅供外部类使用。

 

class Outter {
	private String msg1 = "外部类的私有域";

	
	// -------------------------------------------------------
	// *****错误代码(创建静态属性)******

	// class Inner{
	// private static int age = 9;
	// }

	// -----------------------------------------------------

	// 成员内部类
	// 访问静态属性
	class Inner {
		public void fun() {
			System.out.println(msg1);// 普通内部类调用外部类的方法
		}
	}

	// 使用private 封装
	// 创建私有内部类(仅供外部使用)
	private class Inner {
		public void fun() {
			System.out.println(msg1);// 普通内部类调用外部类的方法
		}
	}

}

public class Test{
	public static void main(String[] args) {
		// 创建Inner对象
		Outter.Inner in = new Outter().new Inner();
		in.fun();
	}
}

总结:(1)成员内部类需要依附与外部类创建而创建,如果有静态变量,代表与对象无关
          (2)成员内部类不能拥有静态属性(静态属性和对象无关)
          (3)但是成员内部类可以访问静态属性

 

(2)、静态内部类-静态方法

           1)、静态内部类的创建不需要外部类,可以直接创建。

           2)、静态内部类不可以访问外部类的任何非static域。

class Outter {
	private static String msg = "外部类的私有域";

	// 静态内部类
	static class Inner {
		// 静态内部类可以拥有自己的成员变量
		private String msg = "静态变量内部的成员变量";

		public void fun() {
			System.out.println(msg);// 普通内部类调用外部类的方法
		}
	}

	// ----------------------------------------------------------------------

	// ===========错误代码=======================
	// 静态内部类 不能访问 外部的 非静态 成员变量

	// private String msg = "外部类的私有域"; // 非静态属性(外部)

	// // 静态内部类
	// static class Inner{
	// public void fun(){
	// System.out.println(msg);// 静态内部类调用外部非静态属性(一定出错)
	// }
	// }

	// -------------------------------------------------------------------

}

public class Test{
	public static void main(String[] args) {
		// 直接产生内部类,没有外部类产生
		Outter.Inner in = new Outter.Inner();
		in.fun();
	}
}

 

(3)、方法内部类

           1)、方法内部类不能使用任何访问权限修饰符 public、 private 、protected均不允许。

           2)、方法内部类对外(方法外)完全隐藏,除了该方法可以访问之外,其余地方均不能访问。

           3)、方法内部类想要使用方法形参,该形参必须使用final声明(JDK8变为隐式的final声明)。

 

class Outter {
	private int age = 5;

	public void display(int num) { // 此处有一个隐式的final
		// 方法内部类
		// 只能在该方法中使用
		class Inner {
			public void fun() {
				// num++; // 因为num不能++,证明了final存在
				System.out.println(num);
				System.out.println(age);
			}
		}
		new Inner().fun(); // 内部类只能在方法内部使用
	}
}

public class Test{
	public static void main(String[] args) {
		Outter outter = new Outter();
		outter.display(10);
	}
}

 

总结:  方法内部类的形参为什么修饰成final????
      因为方法是在栈针中存储的,使用完后直接弹出。而类的对象是在堆中的,两个空间不相同。
      如果方法调用完成后,类还存在(活着),也就是方法都已经弹出栈了,而类的对象还存在, 这是不合理的。所以内部类只能          访问形参,使用final修饰。
    
 

(4)、匿名内部类(方法内部类的特殊版本)

           1)、匿名内部类必须继承一个抽象类或者实现一个接口。

           2)、匿名内部类没有构造方法,因为它没有类名。

interface MyInterface {
	void test(); // 抽象方法
}

class Outter {
	private int age = 5;

	public void display(int num) {

		// 内名内部类
		new MyInterface() { 
			@Override
			public void test() {
				System.out.println(num);
				System.out.println(age);
			}
		}.test(); // 相当于new了一个类,调用它的方法
	}
}

public class Test {
	public static void main(String[] args) {
		Outter outter = new Outter();
		outter.display(10);
	}
}

 

总结: new MyInterface() 代表的不是抽象类,抽象类不能直接new对象,而这里直接使用,代表匿名内部类,实际上隐藏了 class implements。(class implements new MyInterface())

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值