内部类

内部类

内部类:就是在一个类中定义另外一个类!(以后看源码:比如:集合中的迭代器)

  •  在A类中定义一个B类,那么将B类就称为A类的内部类,A类就是B类的外部类!
    
  •  内部类是可以访问外部类的成员,包括私有!
    

内部类的分类:

  • 成员内部类:

    在外部类的成员位置定义的类

  • 局部内部类:

    在局部位置(外部类的成员方法中)定义的一个类

访问方式:

在测试类中,要访问内部类的成员:

  •   外部类名.内部类名 对象名 = 外部类对象().内部类对象();
    
//定义一个外部类
class Outer{
	//成员变量
	private int num = 100 ;
	
	//定义一个内部类(成员内部类 :一般说成员内部类都是默认非静态!)
	class Inner{
		
		//定义一个show()方法
		public void show() {
			System.out.println(num);//直接可以访问外部类包括私有!
		}
	}
	
	//外部类的成员方法:
	public void method() {
		//show();
		//外部类的成员要访问内部类成员,必须通过对象来访问
		//创建内部类对象
		Inner inner = new Inner();
		inner.show();
        
        //局部内部类
		class Inner2{
			
		}
	}
}


public class InnerClassDemo1 {
	
	public static void main(String[] args) {
		//需要在这里来访问成员内部类的成员!
		//外部类名.内部类名 对象名 = 外部类对象().内部类对象();
		Outer3.Inner3 oi = new Outer3().new Inner3() ;
		oi.show();
	}
}

成员内部类它的一些修饰符

  • private :能够保证内部类的数据的安全性

  • static : 静态的成员内部类

  • 被static修饰的成员内部类:

    ​ 它里面的成员方法(可以静态/非静态)只能访问外部类中静态的成员!(必须使用static修饰)

  • 在测试类中,访问静态成员内部类的成员方法的时候,访问方式如下:

    ​ 外部类名.内部类名 对象名 = new 外部类名.内部类名() ;

//定义外部类
class Outer4{
	
	public int num = 100;
	public static int num2 = 50 ;
	
	//加入static修饰的成员内部类
	static class Inner4{
		//定义一个成员方法
		public void show() {
			//System.out.println(num); //外部类的成员变量没有加入static修饰
			System.out.println(num2);
		}
		public static void show2() {
			//System.out.println(num); //外部类的成员变量没有加入static修饰
			System.out.println(num2);
		}
	}
}
//测试类中
public class InnerClassDemo4 {
	
	public static void main(String[] args) {
		//需要访问静态的成员内部类中的成员方法!
		//外部类名.内部类名 对象名  = 外部类对象().内部类对象();
		//Outer4.Inner4 oi = new Outer4().new Inner4();  这种方式行不通!
		
		//静态的成员内部类中成员的访问方式:
		//外部类名.内部类名 对象名 = new 外部类名.内部类名() ;
		Outer4.Inner4 oi = new Outer4.Inner4() ;//类上Inner4此时就相当于外部类的静态成员方法.
		oi.show();

局部内部类:

在局部位置定义的类,

特点:

​ 1)可以直接访问外部类的成员,包括私有!

​ 2)在外部类的成员方法中,可以通过创建局部内部类对象来访问局部内部类的成员

  • JDK7以前(包含JDK7),局部内部类访问局部变量,局部变量必须加入final修饰,否则报错!

  • JDK7以后,局部变量会自动加上final,开发者不需要定义final关键字,为什么要加final?

    原因:

    局部变量的生命周期,随着方法调用而存在,随着方法调用完毕而消失,
    而当前这个局部变量被局部内部类在进行访问(局部内部类对象进行访问),在堆内存中对象不会被立即回收,它还在
    继续使用这个局部变量,需要将这个变量定义为常量,常驻内存---->以便局部内部类对象对该局部变量的访问!

匿名内部类

**匿名内部类:**它是内部类一种简化方式!

  • 格式:

    new 类(可以是具体类,也可抽象类)名/接口名(){

    ​ 重写方法;

    };

    匿名内部类的好处:

    省去了繁杂的代码,不需要定义类里面的子类或者接口的子实现类,写法比较简单!

    匿名内部类的本质就是:继承该类或者是实现了该接口的子类对象!

//定义一个接口
interface Inner{
	//抽象方法
	public abstract void show() ;
	public abstract void show2() ;
}


//定义一个类
class Outer6{ 
		Inner i = new Inner() {

			@Override
			public void show() {
				System.out.println("show Inner");
			}

			@Override
			public void show2() {
				System.out.println("show2 Inner");
			}
			
		};  //相当于接口的子实现类
		i.show();
		i.show2();
	}
	
}
 
public class InnerClassDemo6 {

	public static void main(String[] args) {
			//创建外部类对象
		Outer6 outer = new Outer6() ;
		outer.method();
	}
}

匿名参数类型传递

package com.qianfeng_innerclass_04;
/*
 * 方法形式参数是一个类:	传递该类具体对象
 * 				抽象类:需要传递该抽象类的子类对象
 * 				接口:需要传递该接口的子实现类对象
 * 
 * 
 * 匿名内部类在开发中的使用:
 * 				方法形式参数或者返回值中常见就是形参是抽象类/接口
 * 											 返回值是抽象类/接口
 * */
//定义具体类
class Student{
	public void study() {
		System.out.println("学习JavaEE...");
	}
}
//定义一个StudentDemo类
class StudentDemo{
	public void method(Student s) {//形参传递是具体类
		s.study(); 
	}
}
//测试类
public class InnerClassTest {
	
	public static void main(String[] args) {
		//创建StudentDemo类的方法,访问method方法
		StudentDemo sd = new StudentDemo() ;
		Student s = new Student() ; //具体类可以实例化(最简单,最直接! )
		sd.method(s);
		System.out.println("------------");
		//匿名内部类
		/*
		 * new  类名(具体类名/抽象类类名)/ 接口名(){
		 * 		重写方法;
		 * };
		 * */
		StudentDemo sd2 = new StudentDemo() ;
		sd.method(new Student() {   //具体类!
			
			//重写study方法
			public void study() {
				System.out.println("一鼓作气,再而衰,三而竭!");
			}
			
		});
		
		
	}
}

匿名参数类型传递2

package com.qianfeng_innerclass_04;
/*
 * 方法形式参数如果
 * 			接口:	传递需要改接口子实现类对象
 * 
 * */
//定义一个接口
interface Love{
	void love() ;
}

//定义一个类
class PersonDemo{
	public void function(Love love) {
		love.love();
	}
}
//定义一个子实现类
class Worker implements Love{
	@Override
	public void love() {
		System.out.println("爱生活,爱Java...");
	}
}

//测试类
public class InnerClassTest2 {
	
	public static void main(String[] args) {
		//需要调用PersonDemo类中的function方法
		PersonDemo pd = new PersonDemo() ;
		//Love love = new Love() ;//不能实例化
		//接口多态:
		Love love = new Worker();
		pd.function(love);
		System.out.println("---------------------");
		
		//接口匿名内部类的使用
		PersonDemo pd2 = new PersonDemo() ;
		/*
		 * new 接口名(){
		 * 		重写抽象方法;
		 * };
		 * 
		 * */
		pd2.function(new Love() { //接口匿名内部类对象(本质就是子实现类!)

			@Override
			public void love() {
				System.out.println("爱生活...");
			}
			
		}); 
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值