内部类

一、成员内部类

1、成员内部类:定义在A类里面的B类就是内部类,B类在A类内部地位与其他成员相同,可以相互调用
2、成员内部类的作用:

//这里可以让X同时拥有A B两个类的功能,相当于通过内部类间接实现了多继承
class A{
	
}

class B{
	
}

class X extends A{	//使X拥有A和B的功能,间接实现了多继承
	class Y extends B{
			
	}
}

3、创建成员内部类的两种方法:

public class Demo2 {
	public static void main(String[] args) {
	
		//方法一:先获取内部类的对象再调用方法
		//1.先创建外部类对象
		Outer outer = new Outer();
		//2.创建内部类的对象  构成:外部类对象.new 内部类构造方法
		day12.Outer.Inner inner = outer.new Inner();//使用类的全称是包名.类名
		Inner inner1 = outer.new Inner();//通过导包创建(不推荐使用)
		inner.play();
		
		//方法二:借助于外部类的方法,实现内部类对象的创建并调用方法
		outer.show();
	}
}
class Outer{
	int age;
	
	class Inner{//内部类
		int height = 170;
		
		public void play(){
			System.out.println("Inner-play");
		}
	}
	
	public void show() {
		System.out.println("Outer-show"+age);
		
		//创建内部类对象并调用方法
		Inner inner = new Inner();
		inner.play();
	}
}

二、局部内部类

1、局部内部类:定义在外部类方法中的类
局部内部类的作用范围:从定义它开始到他所在的方法结束
2、局部内部类的功能:

  • 通过局部内部类实现方法功能的私有化
  • 对方法内部的代码进行整理,增强了代码的可读性和可操作性

class Temp{

    //实现的功能:只允许play调用gongneng1()和gongneng2(),run()不能调用
    //方法之间不能嵌套,但方法中可以放内部类
    public void play() {
    		class Inner{
    			public void gongneng1() {
    				
    			}
    			
    		public void gongneng2() {
    			
    		}
    		
    	}
    	Inner inner = new Inner();
    	inner.gongneng1();
    	inner.gongneng2();
    }
    
    public void run() {
    	//两个小方法对run不可见
    	//gongneng1();
    	//gongneng2();
    }	
}

3、
了解:
局部内部类所在的方法中局部变量的使用.

  • 局部变量的作用域:定义变量开始到函数结束
  • final:被final修饰的变量会被放在常量区,而常量区的值存在的时间要大于局部变量所在的方法,相当于从原来的基础上扩大了作用域

原理:

  • 当方法中同时存在局部内部类与局部变量时,局部变量的使用范围就会从原来的基础上进行扩大.

原因:

  • 在当前的情况下,程序会默 认让final去修饰weight.所以当局部变量所在的方法结束的时候,变量没有被释放,保存的值还在.

  • 关于变量前面的final:

前提:变量必须与局部内部类同时存在.
在jdk1.7之前要想保住局部变量的值,要手动添加final
在jdk1.7之后,java的内部机制已经在变量的前面默认添加了final

public class Demo3 {

 public static void main(String[] args) {

//创建Outer1对象
Outer1 outer1 = new Outer1();
    		outer1.show();
    	}
    }
    class Outer1{
    	int age;

public void show() {
	System.out.println("Outer-show"+age);
	/* final */int weight = 20;	//前面默认又final,延长使用寿命,防止其随show方法结束而消失
	
	class Inner{	//局部内部类
		int height = 170;
		
		public void play(){
			System.out.println("Inner-play");
		}
	}
	
	//创建内部类对象并调用方法
	Inner inner = new Inner();
	inner.play();
}
}

三、静态内部类

public class Demo4 {
	public static void main(String[] args) {
		//静态的对象
		//注意:要保证内部类是静态的
		//构成:new 外部类.内部类的构造方法
		Outer3.Inner inner = new Outer3.Inner();
		//调用非静态方法
		inner.play();
		//调用静态方法
		Outer3.Inner.show();
	}
}

class Outer3{	
	
	static class Inner{	//静态内部类
		int height = 170;
		//非静态方法
		public void play(){
			System.out.println("Inner-play");
		}
		//静态方法		
		public static void show() {
			System.out.println("Inner-show");
		}
	}
	
}

注意点:

  • 1.静态内部类中可以没有静态的成员
  • 2.有静态成员的一定是静态内部类
    (和抽象类一个脾气。。。)

四、匿名内部类

1、匿名内部类(对象):定义在一个类方法中的匿名子类对象,属于局部内部类

  • 匿名对象和匿名子类对象
  • 匿名内部类对象

public class Demo5 {

public static void test(Animal animal) {
		animal.eat();
	}
public static void main(String[] args) {
	Animal animal = new Animal();
	animal.eat();
	//匿名对象:没有名字的对象,只能在创建的时候使用一次,之后会变成垃圾等待回收
	//场景:可以作为参数传递		作用:节省代码,节省内存
	new Animal().eat();
	test(new Animal());
	
	//创建匿名子类对象
	//第一种创建方式
	//使用已有的子类创建匿名子类对象并调用方法
	//场景:现有的子类可以使用多次---相同的功能需要调用多次的时候
	new Dog().eat();
	//第二种创建方式
	//直接创建没有名字的Animal的匿名子类对象
	//构成:new + 父类/父接口的名字 + () + {匿名子类的执行体};
	//场景:只能使用一次,使用完会被回收---每次都使用不同的功能
	new Animal() {
		@Override
		public void eat() {
			System.out.println("匿名子类---eat");
		}
		public void show() {	//写第二个方法没有意义,因为通过匿名子类对象一次只能调用一个方法,调用之后即被回收,第二个方法写了也调用不了
			System.out.println("show");
		}
	}.eat();	//直接创建匿名子类对象并调用匿名子类中的方法
	
	//研究匿名内部类
	Out out = new Out();
	out.show();
	
	
}
}

//研究匿名对象和匿名子类对象
class Animal{
	public void eat() {
		System.out.println("Animal-eat");
	}
}

class Dog extends Animal{
	public void eat() {
		System.out.println("Dog-eat");
	}
}

//研究匿名内部类
class Out{
	public void show() {


new Animal() {
		@Override
		public void eat() {
			System.out.println("匿名子类---eat");
		}
		public void show() {	//写第二个方法没有意义,因为通过匿名子类对象一次只能调用一个方法,调用之后即被回收,第二个方法写了也调用不了
			System.out.println("show");
		}
	}.show();
}
//使用普通的匿名对象充当参数
public void canshu1() {
	System.out.println(new Animal());
}
//匿名内部类充当参数
public void canshu2() {
	System.out.println(new Animal() {
		
	});
}
//使用普通的匿名对象充当返回值
public Animal fanhuizhi1() {
	return new Animal();
}
//匿名内部类充当返回值
public Animal fanhuizhi2() {
	return new Animal() {
		@Override
		public String toString() {
			return "哈哈";
		}
	};
	}
}


//自己测试创建接口的匿名内部类---作为参数,返回值
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值