内部类

内部类:
定义:内部类就是定义在一个类的内部的类,与之对应的包含内部类的这个类叫做外部类。换种方式说,就是可以允许在一个类的内部再定义一个类。“寄生类”。
为什么使用内部类:每一个类都可以独自的继承一个父类以及实现若干个接口。所以外部类是否继承一个类对于内部类没有影响。如果没有内部类提供的可以继承抽象的或者具体的类的能力,一些编程问题就很难解决(比如说就需要继承多个类)。接口解决了部分问题,内部类有效的实现了“多继承”。

1、成员内部类:
内部类定义在外部类的内部,和属性,方法是并列的关系,相当于外部类的一个成员属性。既然是属性,就可以使用四种访问控制修饰符来修饰。
例如:ClassRoom.java

/***
 * 想让这个ClassRoom具备 建筑,家具,电器的功能,不可能同时
 * 继承三个父类
 * @author Administrator
 *使用内部类的方式,这个ClassRoom就具备建筑功能的同时,它的内部
 *还具备家具,电器的功能。
 */
public class ClassRoom extends Building{
	//Desk Computer都作为类的属性(成员)来看待,所以
	//Desk Computer都是成员内部类
	class Desk extends Furniture{};
	class Computer extends Machine{};
	double area;//教室的面积属性
	

}

成员内部类里面的方法可以直接访问外部类的所有数据,包括私有的。
例如定义一个School.java类

/***
 * 
 * 外部类
 *
 */
public class School {
	public String name;//校名
	public String addr;//校址
	private String 操场;//这里把操场设置为私有
	public String get操场() {
		return 操场;
	}
	public void set操场(String 操场) {
		this.操场 = 操场;
	}
	public void 开学(){
		//不能直接访问内部类的属性,因为外部类对象存在的情况下
		//内部类对象不一定存在
//		System.out.println(班长);
	}
	
	//这是一个成员内部类,它的对象就是具体的班级
	public class Class{
		String 班长;//班长
		int num;//人数
		String 操场;//学校比较大气,每一个班都有自己的操场
		//班级拥有的方法,比如说“上体育课”,在这个方法内部是可以
		//使用外部类的私有属性“操场的”
		public void 上体育课(){
			System.out.println(操场);
			//System.out.println(School.this.操场);打印的就是内部类的操场
		}
		public void 上自己班的操场() {
			System.out.println(操场);
		}
	}

}

定义了成员内部类之后,必须使用外部类的对象才能创建内部类的对象。
内部类 内部类对象名 = 外部类对象.new 内部类()
例如来一个测试类

/***
 * 成员内部类的测试。
 * 案例:创建安工程17计算机1班,然后让这个班级上体育课
 * 步骤:首先要有安工程,再创建班级,再调用上体育课
 * @author Administrator
 *
 */
public class SchoolTest {
	public static void main(String[] args) {
		//创建安工程对象
		School 安工程 = new School();
		安工程.name="灰尘大";
		安工程.addr="北京路8号";
		安工程.set操场("风雨操场");
		//创建班级
		Class 计算机171= 安工程.new Class(); 
		计算机171.班长="张三";
		计算机171.num=50;
		计算机171.操场="计算机17届1班自己的操场";
		计算机171.上体育课();		
		计算机171.上自己班的操场();
		/*1、如果内部类的某一个属性和外部类属性重名,
		 *   怎么使用外部类的那个属性?
		 *2、外部类的方法可不可以直接使用内部类的数据
		 *3、内部类能不能访问外部的静态资源
		 *4、内部类能不能有静态的资源 
		 */
	}
}

当内部类的某一个属性和外部类的某一个属性重名时,如果想使用外部类的这个属性, 外部类.this.属性名 的方式

外部类的方法是不能直接访问内部类的数据的,因为外部类对象存在的情况下,内部类对象不一定存在。

内部类是不能有静态资源的,因为所有的内部类对象都依赖于一个外部类对象,这个时候在内部类声明静态资源就没有意义了,也就是说外部类的属性就相当于内部类的静态资源。

2、静态内部类
内部类用static修饰,思考以下问题
—静态内部类中的方法能不能直接访问外部类的资源(资源分为静态和非静态资源)
答:静态的可以,非静态不行在这里插入图片描述
—静态内部类的属性和外部类的属性重名了,如何进行操作才能访问外部类的属性。
如果想使用外部类的这个属性, 外部类.属性名 的方式
在这里插入图片描述
—如如何创建静态内部类的对象。
直接创建,和之前最普通的一样。

Test t=new Test();//接上面的图片

—外部类能不能直接访问静态内部类的资源(资源分为静态和非静态资源)
静态属性直接 内部类.属性访问
非静态用new 内部类().属性的方式访问

public class TestInClassDemo {
	 static int a=5;
	public void p() {
		System.out.println(new Test().a);//打印6
		System.out.println(Test.b);//打印7
	}
	static class Test{
		int a=6;
		static int b=7;
		public void print() {
			System.out.println(a);	
			System.out.println(TestInClassDemo.a);
		}
		
	}

3、局部内部类
方法中定义的类,只在这个方法中可见,别的地方是无法访问的,所有不能用访问控制修饰符修饰。
局部内部类中是可以访问外部类的属性的,因为此方法是某一个外部类的对象来调用,外部类的对象就肯定存在,所以内部类可以访问外部类的属性。
局部内部类只能访问该方法的final的变量。也就是说局部内部类中不可以访问方法中有可能会变的那些变量。
因为:局部内部类使用方法的变量时,就是局部内部类的对象去访问它,内部类的对象整个生命周期中都有可能去修改这些变量,为了保证数据的一致性,就规定不可以访问有可能会变的那些变量。
在JDK1.8之后,也是可以访问不用final修饰的方法的变量。只要保证在局部内部类中不做修改就可以。

public class School {
	int a=5;
	public void Test() {
		int b=6;
		class building{	
			public void print() {		
				System.out.println(a);
				System.out.println(b);
			}
		}
		building bi=new building();
		bi.print();
	}
	public static void main(String[] args) {
		School s=new School();	
		s.Test();
	}

}

4、匿名内部类:
没有名字,也不存在的一个类,我们只去关注它对于父类方法的实现(或者说对于接口方法的实现),而且只关注一次。
在一段程序中需要创建一个类的对象,通常这个类继承自某一个父类或者实现若干接口,而且这个类的对象在我们创建之后,这个类就没有存在的价值了,此时可以使用匿名内部类的机制。

import java.util.Timer;
import java.util.TimerTask;

public class Demo {

	public static void main(String[] args) {
		Timer t=new Timer();
		t.schedule(new TimerTask() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				System.out.println("lihai ");
			}
		}, 10, 500);

	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
、Person的多态性设计。 设计一个Person,其包含一个方法pay(),计算工资支出。再从Person派生出助教(Assistant)、讲师(Instructor)、副教授(AssistantProfessor)和教授(Professor)。其:工资支出=基本工资+授课时数teachingHours*每课时课金。 助教基本工资为800元,每课时课金25元;讲师基本工资为1000元,每课时课金35元;副教授基本工资为1200元,每课时课金40元;教授基本工资为1400元,每课时课金50元;在主方法显示各人员的工资支出。用以下两种方式实现: ○1将Person设计为抽象,pay()为抽象方法,设计程序实现多态性。 ○2将Person设计为接口,设计程序实现多态性。 提示:设置授课时数teachingHours为成员变量,计算工资支出为成员方法,考虑是否定义构造方法。 2、编写一个Java程序,在程序定义一个接口Achievement,其一个计算平均分的抽象方法avg();定义一个Person,其有数据成员:姓名name和年龄age,构造方法初始化数据成员name和age,重写toString()方法显示成员信息;定义一个Student继承Person并实现接口Achievement,增加数据成员:语文成绩chnScore、数学成绩mathScore和英语成绩engScore,增加设置三门课成绩的setScore()方法,并实现接口Achievement的计算平均分的抽象方法avg(),主函数测试,部分代码如下所示: Student s=new Student(“张三”,16); //创建子对象 System.out.println(s.toString()); //显示s的个人信息,调用继承父的toString方法 s.setScore(80,88,95); //设置三门课的成绩 System.out.printf(“三门课的平均分:%.2f”, s.avg()); //显示对象s的三门课的平均分 输出结果如下: 姓名:张三,年龄:16 三门课的平均分:87.67 3、编写一个Java程序,在程序定义一个School,在School定义一个内部类Student,分别创建这两个的对象,访问各个对象的方法,其School: 数据成员:学院名称schoolName; 成员方法:显示信息方法showSchoolMsg():在方法创建内部类Student的对象,并显示该对象的信息(调用内部类Student的显示信息的成员方法)。 Student: 数据成员:姓名sname,年龄sage; 构造方法,初始化姓名sname、年龄sage以及所属学院名(即外部数据成员:学院名称schoolName); 成员方法:显示信息showStudentMsg(),显示的信息包括:姓名、年龄以及所属学院名。 主函数测试,部分代码如下所示: …… // 创建外部School的对象 …… // 通过外部对象调用其显示信息的方法showSchoolMsg() System.out.println(“-------------我是华丽的分割线-------------”); …… // 创建内部类Student的对象 …… // 通过内部类对象调用其显示信息的方法showStudentMsg()

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值