面向对象---内部类

前面提到,如果形式参数是接口,传统的方式是提供接口的子实现类来实现接口多态,但是在实际开发中经常使用内部类的方式,这种方式不需要提供子实现类,我们这节就来学习一下内部类。

先通过一个例子来感受一下内部类:

在没有内部类之前:

interface Inter2{
	public abstract void study();
}
//具体类
class StudentDemo{
	public void method(Inter2 i) {//Inter2 i = new Inter2() ;//错误
		i.study();
	}
}
class InterImpl2 implements Inter2{

	@Override
	public void study() {
		System.out.println("好好学习,天天向上...");
	}	
}
//测试类
public class Demo {

	public static void main(String[] args) {
		//需求:需要调用StudentDemo这个类中method()方法
		StudentDemo sd = new StudentDemo() ;
		//接口多态的形式
		Inter2 i = new InterImpl2() ;
		sd.method(i);
	}
}

用内部类的方法:

interface Inter2{
	public abstract void study();
}
//具体类
class StudentDemo{
	public void method(Inter2 i) {//Inter2 i = new Inter2() ;//错误
		i.study();
	}
}
//测试类
public class Demo {

	public static void main(String[] args) {
		//需求:需要调用StudentDemo这个类中method()方法
		StudentDemo sd = new StudentDemo() ;
		Inter2 i2 = new Inter2() {
			
			@Override
			public void study() {
				System.out.println("好好学习,天天向上...");
			}
		};
		sd.method(i2);
	}
}

一、内部类的概念

内部类:
在B类内部定义A类,A类就属于B的内部类
   内部类访问外部类的特点:
  它可以直接访问外部类的成员,包括私有
  外部类如何访问内部类的成员?

  通过创建内部类对象的方式间接访问...

class Outer{
	int num = 100 ;
	private int num2 = 200 ;
	//Inner就是Outer的内部类
	class Inner{
		//内部类的方法
		public void show() {
			System.out.println(num);
			System.out.println(num2);
		}
	}
	//外部类的成员位置
	public void method() {
//		show() ;
		//只能创建内部类对象的方式
		Inner i = new Inner() ;
		i.show();
	}
}
//测试类
public class OuterDemo {

	public static void main(String[] args) {
		
	}
}

可以看出,在内部类中打印num和num2都没有问题,说明内部类可以直接访问外部类的成员,包括私有。

而在外部类的成员方法中直接调用内部类的show方法则会报错,说明外部类不能直接访问内部类的成员,如果要调用,只能采取在外部类中创建内部类对象的方式来间接访问。

二、内部类的分类

    根据内部类的位置,可以将内部类分为两类:成员内部类和局部内部类

        成员内部类:在外部类的成员位置

        局部内部类:在外部类的局部位置

class Outer2{
	
	//在成员位置:成员内部类
	//class Inner2{
	//		
	//}
	
	public  void method() {
		//在局部位置:局部内部类
		class Inner{
			
		}
	}
}

1、成员内部类

    成员内部类:

    可以直接外部类的成员,包括私有

     外部类要访问内部类(非静态的内部类)的成员方法:

      格式:外部类名.内部类名 对象名 = new 外部类对象.new内部类对象

我们通过具体代码来感受一下:

class Outer3{
	//外部类的成员变量
	private int num = 10 ;
	
	//成员内部类
	class Inner3{
		//show()
		public void show() {
			System.out.println(num);//成员内部类可以直接访问外部类的成员,包括私有
		}
	}
}
//测试类
public class OuterDemo3 {
	
	public static void main(String[] args) {
		//格式:外部类名.内部类名 对象名 = new 外部类对象.new 内部类对象
		Outer3.Inner3 oi = new Outer3().new Inner3();
		oi.show(); 
	}
}
 关于成员内部类的修饰符:
   private:  作用:保证数据的安全性!
   static修饰:可以把静态内部类看成是外部类的成员.
   特点:

   静态成员内部类访问外部类的数据,该数据必须static修饰

外部类要访问内部类(静态)的成员方法: 

        格式:外部类名.内部类名 对象名 = new 外部类对象.内部类对象

class Outer4{
	private int num = 10 ;
	private static int num2 = 100 ;
	
	//成员内部类:静态的
	static class Inner4{
		//成员方法
		//非静态的内部类成员方法
		public void show() {
			//System.out.println(num); //静态成员内部类访问外部类的数据,该数据必须static修饰
			System.out.println(num2);
		}	
		
		//静态的内部类的成员方法
		public static void show2() {
                        //System.out.println(num);
			System.out.println(num2);
		}
	}
}
//测试类	
public class OuterDemo4 {

	public static void main(String[] args) {
	
		//对于静态的成员内部类的访问格式
		//外部类名.内部类名 对象名 = new 外部类名.内部类名() ; //把静态的成员内部类看成了外部类的成员
		Outer4.Inner4 oi =  new Outer4.Inner4() ;
		oi.show();
		oi.show2();
	}
}

由于静态成员内部类访问外部类的数据,该数据必须static修饰,无论该方法是否为静态方法,所以只能打印静态的num2值,打印num则会报错,外部类要访问静态的内部类时,需要特定的访问格式:外部类名.内部类名 对象名 =new 外部类名.内部类名() ;此时把静态的成员内部看成了外部类的成员,可以通过类名直接调用。

2、局部内部类

局部内部类
   可以访问外部类的成员包括私有... 
  在外部类的局部位置去访问内部类的show( ),需要在局部位置创建内部类对象,通过对象去访问

//定义外部类
class Outer5{
	private int num = 10 ;
	//定义外部类的成员方法
	public void method() {
		//变量
		final int num2 = 20 ;  //jdk1.8不会有问题..	
		//定义局部内部类
		class Inner5{
			public void show() {
				System.out.println(num);
				//注意事项:在这块改变量继续被使用...将变量变成固定值:在内存始终存在(被内部类的成员去使用)
				System.out.println(num2); 
			}
		}
		//创建对象
		Inner5 i = new Inner5() ;
		i.show();  //调用show()
	}
}
public class OuterDemo5 {
	public static void main(String[] args) {
		//创建对象
		Outer5 o = new Outer5() ;
		o.method();
	}
}

三、匿名内部类

前提是有一个类或者接口
   这个类可以是具体类也可以是抽象类
   new 类名或者接口名{
   方法重写();
   }
匿名内部类的本质:

   是继承了该类或者实现了该接口子类对象...

//定义一个接口
interface Inter{
	public abstract void show();
	public abstract void show2() ;	
}
//定义一个类实现这接口...
class Outer6{
	//成员方法
	public void method() {
		//调用接口一个方法的时候:匿名内部类的形式
		//两个方法调用
	/*	new Inter() {
			
			@Override
			public void show2() {
				System.out.println("show2....");
			}
			
			@Override
			public void show() {
				System.out.println("show...");
			}
		}.show();
		
		new Inter() {
			
			@Override
			public void show2() {
				System.out.println("show2....");
			}
			
			@Override
			public void show() {
				System.out.println("show...");
			}
		}.show2();*/
		
		//上述非常麻烦:直接创建对象,给它起名字
		Inter i = new Inter() {
			
			@Override
			public void show2() {
				System.out.println("show2...");
			}
			
			@Override
			public void show() {
				System.out.println("show....");
			}
		};
		i.show();
		i.show2();
	}
}
public class OuterDemo6 {
	
	public static void main(String[] args) {
		//创建Outer6类的对象
		Outer6 o = new Outer6() ;
		o.method();
	}
}
一道匿名内部类面试题:
按照要求,补齐代码
interface Inter { void show(); }
class Outer { //补齐代码 }
class OuterDemo {
public static void main(String[] args) {
Outer.method().show();
}
}

要求在控制台输出”HelloWorld”

分析:

    Outer.method().show(); ---->Outer.method() :当前这个method方法是静态方法(因为可以直接通过类名调用)

    因为可以直接调show方法:Outer.method().show();---->Outer.method()返回一个对象.show()---->由于show()方法是一个接口中的方法,返回值是一个接口类型,当前并不提供接口的子实现类,所以只能用匿名内部类

代码如下:

interface Inter { void show(); }
class Outer { //补齐代码 
	public static Inter method() {
		return new Inter() {

			@Override
			public void show() {
				System.out.println("HelloWorld");
			}
		};
	}
}
class OuterDemo {
	public static void main(String[] args) {
		  Outer.method().show();
	  }
}
至此,面向对象部分结束。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值