内部类

内部类的定义:在类内部进行其他类结构嵌套操作

一、存在意义(优点):

1、内部类与外部类可以方便的访问彼此的私有域(包含私有方法和私有属性)

eg:内部类

class Outter{
	private String msg = "Outter中字符串";
	//内部类
	class Inner{
		private String inMsg = "Inneer中字符串";
		public void fun(){
			//直接调用外部类的私有属性
			System.out.println(msg);
		}
	}
	public void test(){
		//生产内部类对象
		Inner in = new Inner();
		in.fun();
	}
}
public class Study{
	
	public static void main (String[] args){
		Outter out = new Outter();
		out.test();
	}
}

 

两个互相独立的类实现上述功能:(明显更加复杂)

class Outter{
	private String msg = "Outter中字符串";
	public String getMsg(){                           //8
		return this.msg;
	}
	public void test(){                 //2.1
		//this表示当前对象    即“Outter out = new Outter();”中的out
		Inner in = new Inner(this);      //3
		in.fun();                         //5
	}
}

class Inner{
		private String inMsg = "Inneer中字符串";
		private Outter out;
		//构造注入
		public Inner (Outter out){                               //3.1
			this.out = out;    //为Inner中的out变量初始化         //4
		}
		public void fun(){                                           //6
			//直接调用外部类的私有属性
			System.out.println(out.getMsg());                    //7
		}
	}
	
public class Study{
	
	public static void main (String[] args){
		Outter out = new Outter();     //1   表示第一步
		out.test();                     //2
	}
}

 

2、内部类是另外一种封装(保护性),对外部的其他类隐藏 (eg:心脏包在人身体内部)

3、内部类可以实现JAVA单继承的局限(如下代码)

class A{
	private String msg = "test";
	public String getMsg(){
		return msg;
	}
}

class B{
	private int age = 20;
	public int getAge(){
		return age;
	}
}

class C{
	class InnerClassA extends A{
		public String name(){
			return super.getMsg();
		}
	}
	
	class InnerClassB extends B{
		public int age(){
			return super.getAge();
		}
	}
	
	public String name(){
		return new InnerClassA().name();
	}
	public int age(){
		return new InnerClassB().age();
	}
}

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

二、缺点

结构复杂!

三、内部类与外部类的关系

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

2、内部类只一个相对独立的个体,与外部类没有is-a关系。

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

在创建内部类的时候外部类的对象就会传进来

内部类可以直接访问外部类的元素(包含私有域):

class Outter{
	private String msg;
	private int age;
	
	class Inner{
		public void display(){
			msg = "test";           //相当于Outter.this.msg = "test";
			age = 20;               //相当于Outter.this.age = 20; 
			System.out.println(msg);
			System.out.println(age);
		}
	}
	
	public void test(){
		Inner in = new Inner();
        in.display();		
	}
}

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

外部类不可以直接访问内部类元素,需要通过内部类的引用间接访问:

class Outter{
	
	class Inner{
		private String msg = "InnerClass";
	}
	
	public void test(){
		Inner in = new Inner();
        System.out.println(in.msg);	
	}
}

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

四、创建内部类语法(在外部类外部创建)

1、创建非静态内部类

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

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

2、创建静态内部类

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

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

3、在外部类的内部创建内部类与在主方法中创建普通对象一样

eg:Inner in = new Inner();

五、内部类的分类

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

1.1成员内部类不能存在任何static变量或方法,但是可以访问外部类的静态域。

class Outter{
	private String name = "test";
	private static int age = 20;
	
	class Inner{
		private static int age = 50;    //错误
		public void fun(){
			System.out.println(name);
            System.out.println(age);				
		}
	}
}

public class Study{
	public static void main (String[] args){
		Outter.Inner in = new Outter().new Inner();
		in.fun();
	}
}

就像在普通方法中不能只用static变量,因为static不依赖于对象而普通方法依赖于对象

class Outter{
	private String name = "test";
	private static int age = 20;
	
	public void test(){
		static int age = 5;     //错
	}
}

public class Study{
	public static void main (String[] args){
		Outter.Inner in = new Outter().new Inner();
		in.fun();
	}
}

1.2成员内部类依附外部类,所以只有创建的外部类才能创建内部类。

class Outter{
	private String name = "test";
	private static int age = 20;
	
	class Inner{
		public void fun(){
			System.out.println(name);
            System.out.println(age);				
		}
	}
}

public class Study{
	public static void main (String[] args){
		Outter.Inner in = new Outter().new Inner();
		in.fun();
	}
}

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

2.1静态内部类的创建不需要依赖外部类,可以直接创建。

2.2静态内部类不可以使用任何外部类的非static域(包含属性和方法),但是可以存在自己的成员变量。

静态内部类不可以使用任何外部类的非static域:

class Outter{
	private String name = "test";
	private static int age = 20;
	
	static class Inner{
		public void fun(){
			System.out.println(name);     //错
                        System.out.println(age);			
		}
	}
}

public class Study{
	public static void main (String[] args){
		Outter.Inner in = new Outter.Inner();
		in.fun();
	}
}

静态内部类不可以使用外部类的static变量,属性:

class Outter{
	private String name = "test";
	private static int age = 20;
	
	static class Inner{
		public void fun(){
                   System.out.println(age);				
		}
	}
}

public class Study{
	public static void main (String[] args){
		Outter.Inner in = new Outter.Inner();
		in.fun();
	}
}

但是可以存在自己的成员变量:

class Outter{
	private String name = "test";
	private static int age = 20;
	
	static class Inner{
		private String name;
		public void fun(){
            System.out.println(age);				
		}
	}
}

public class Study{
	public static void main (String[] args){
		Outter.Inner in = new Outter.Inner();
		in.fun();
	}
}

3、方法内部类

3.1方法内部类不允许使用访问权限修饰符public  private  protected均不允许

3.2方法内部类对外部完全隐藏,除了创建这个类的方法可以访问它以外,其他地方均不能访问

3.3方法内部类如果想使用方法形参,该形参必须使用final声明(JDK8将形参变为隐式final声明)l

class Outter{
	private int num = 5;
	public void display(int temp){
		//方法内部类
		class Inner{
			public void fun(){
				System.out.println(num);     //普通方法可以访问类中的属性
				System.out.println(temp);
			}
		}
		new Inner().fun();          //在方法中
	}
}
public class Study{
	public static void main (String[] args){
		Outter out = new Outter();
		out.display(20);
	}
}

如何证明形参被final修饰了:

class Outter{
	private int num = 5;
	public void display(int temp){
		//方法内部类
		class Inner{
			public void fun(){
				System.out.println(num);     //普通方法可以访问类中的属性
				temp++;      //证明形参被final修饰
				System.out.println(temp);
			}
		}
		new Inner().fun();          //在方法中
	}
}
public class Study{
	public static void main (String[] args){
		Outter out = new Outter();
		out.display(20);
	}
}

4、匿名内部类(lamdba表达式前身)

匿名内部类就是一个没有名字的方法内部类,因此特点与方法内部类完全一样,除此之外,还有:

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

interface MyInterface{
	void test();
}

class Outter{
	private int num = 5;
	public void display(int temp){
		//匿名内部类,匿名的实现了MyInterface的接口
		new MyInterface(){
			public void test(){
				System.out.println("匿名的实现了MyInterface的接口");
				System.out.println(temp);
			}
		}.test();
	}
}
public class Study{
	public static void main (String[] args){
		Outter out = new Outter();
		out.display(20);
	}
}

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

 

------------------------------------------------------------------------------------------------------------------------终于写完了----------------------------------

------------------------------------------------------------------------------------------------------------------------THE  END-----------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值