15.内部类

内部类

在一个类的内部定义另一个类-----------》成员内部类

在一个方法的内部定义另一个类--------》局部内部类
成员内部类

案例:

描述班级 班级类  班级名称 班级人数 

描述学员 学生类	学员名称 学员性别



只能在班级类中 访问到学生类 其他类中 不准访问学生类
//外部类
public class Classes {

	public String className;
	public int classNum;
	public Student[] ss = new Student[15];
    public Classes() {
		//外部类空参构造
	}
	public Classes(String className, int classNum) {
        //外部类带参构造
		super();
		this.className = className;
		this.classNum = classNum;
	}
    
	//在Classes类的内部 声明了一个Student类 成员内部类
	public class Student{
		public String name;
		public int age;
		
		public Student(String name,int age) {
			this.name = name;
			this.age = age;
		}
		public Student(String className,int classNum,String name,int age) {
			Classes.this.className = className;
			Classes.this.classNum = classNum;
			this.name = name;
			this.age = age;
		}

		@Override
		public String toString() {
			return "Student [name=" + this.name + ", age=" + age + "]";
		}
		
		public void show() {
			//通过外部类名.this可以访问到外部类属性
			System.out.println(Classes.this.className+" "+Classes.this.classNum+" "+this.name + " "+this.age);
		}
		
	}
	
	
	@Override
	public String toString() {
		return "Classes [className=" + className + ", classNum=" + classNum + "]";
	}
	//外部类成员方法
	public void show() {
		//外部类成员方法 拿到成员内部类的属性
		//可以创建内部类对象
		Student s = new Student("三三",12);
		System.out.println(s.name+" "+s.age);
		System.out.println(s.toString());
	}
	
}

//测试类
//创建外部类对象
Classes c = new Classes("开发1班",52);
//通过外部类对象 创建内部类对象
Classes.Student s = c.new Student("张三",18);
//通过内部类对象引用名 调用内部了的方法
s.show();

//使用匿名对象声明方式 创建外部类对象 内部类对象 并利用函数式编程 直接调用内部类方法
new Classes().new Student("开发2班",64,"李四",23).show();

练习:

class Shop	String shopName	int goodsNum

内部类 class Goods 	String name	double price	 void show() 展示所有四个属性

测试类通过构造方法 创建商品对象 并展示四个属性值
局部内部类

成员方法中 添加一个类结构 只能在当前方法中创建类的对象

	//成员方法
	public void show(String stuName,int stuAge,String teaName,int teaAge) {
		
        int count = 5;//局部变量 如果被局部内部类访问了 则默认成为一个常量 值不可改变
		//count = 6;	//报错
        //变量会随着方法出栈消失 导致局部内部类编译失败
        //常量则不会消失 即使方法出栈 局部内部类的class文件 依然正常
		
		//在成员方法中 设计类结构  局部内部类
		class Teacher{
			public String teaName;
			public int teaAge;
            //int count = 7;//如果局部内部类中 有与局部变量同名的变量 
            //那么局部内部类访问的就是同类中的这个变量 方法中的变量依然是变量
			
			public Teacher(String teaName,int teaAge) {
				this.teaName = teaName;
				this.teaAge = teaAge;
			}
			public void show1(String name,int age) {
				Student s = new Student(name,age);
				System.out.println(Classes.this.className+" "+Classes.this.classNum+" "+this.teaName+" "+this.teaAge+" "+s.name+" "+s.age);
//				count = 7;
//				int c = count;
				System.out.println(count);
                //局部内部类 使用了局部变量count 意味count是一个常量 
			}
		}
        
        //在局部内部类所在方法中 创建局部内部类对象 并调用方法
		Teacher t = new Teacher(teaName,teaAge);
		t.show1(stuName, stuAge);
		
	}

//测试类
new Classes("开发99",50).show("豆豆",18,"张老师",30);
内部类使用

案例:

接口类 功能 打印

实现类 1.彩色打印机 2.黑白打印机

public interface Print{
    public void print();
}

//直接在测试类中 通过内部类的形式 编写实现类代码
	Print color = new Print(){
        //设计实现类 并且返回实现类对象
        public void print(){
            syso("彩色打印机打印彩色");
        }
    };
	color.print();//实现类对象 调用 实现的方法

	//匿名实现类对象
	new Print(){
        public void print(){
            syso("黑白打印机打印黑白");
        }
    }.print();

特点:如果实现类 除了实现某个接口的功能外 没有任何其他作用 则可以使用内部类结构 不再单独声明实现类

练习:我们直到集合中有一个removeIf(Predicate filter) 参数需要放置的是Predicate接口的实现类对象 请使用内部类的形式 删除原int集合中所有偶数

	ArrayList<Integer> ai = new ArrayList<Integer>();
	...
    ai.removeIf(new Predicate<Integer>() {
		@Override
		public boolean test(Integer t) {
			// TODO Auto-generated method stub
			return t%2==0;
		}
	});
	for(int i : ai) {
		System.out.print(i+" ");
	}
接口作为方法的参数
特点:实参用内部类编写
接口作为方法的返回值
特点:return 返回一个内部类编写的实现类对象

案例:

interface Eat--->eat()

class Util

	----->void  show1(Eat)  功能 调用eat()		准备实参的时候实现

	----->Eat show2()------->			return前实现  ----》调用方法 获取返回值 调用eat()
public class Util {

    //以父类作为形参	实参可以放任意子类对象
    //以接口作为形参	实参可以放任意实现类对象
	//以接口作为 方法的参数 传实参时 再去创建实现类对象
	public void show1(Eat e) {
		e.eat();
	}
	
    //以父类作为方法的返回值类型	则可以返回任意子类对象
    //以接口作为方法的返回值类型 则可以返回任意实现类对象
	//接口作为方法的返回值  应该返回一个该接口的实现类对象
	public Eat show2(int i) {
		Eat e = null;
		if(i==1) {
			//接口实现类对象1 
			e = new Eat() {
				@Override
				public void eat() {
					// TODO Auto-generated method stub
					System.out.println("猫吃鱼");
				}
			};
		}else {
			//接口实现类对象2
			e = new Eat() {
				@Override
				public void eat() {
					// TODO Auto-generated method stub
					System.out.println("狗啃骨头");
				}
			};
		}
		//以接口作为方法的返回值类型  一定要在返回前 实现该接口
		return e;
	}
}

	//测试类
		Scanner input = new Scanner(System.in);
		System.out.println("1.猫2.狗");
		int i = input.nextInt();
		
		Util u = new Util();
		Eat e2 = u.show2(i);//根据用户的输入 返回某个接口实现类对象
		//e2.eat();	//通过返回值(实现类对象)调用实现的方法


		u.show1(e2);//传入一个接口的实现类对象 作为实参


		//或者在调用带参方法前 先准备接口实现类对象作为实参
		Eat e1 = new Eat() {
			@Override
			public void eat() {
				// TODO Auto-generated method stub
				System.out.println("狗啃骨头");
			}
		};
		u.show1(e1);
		u.show1(new Eat(){
            @Override
			public void eat() {
				// TODO Auto-generated method stub
				System.out.println("狗啃骨头");
			}
        });
Lambda表达式
函数式接口 :只有一个抽象方法的接口
@FunctionalInterface
//通过在接口上添加主键 来约束当前接口只能是函数式接口 否则报错
public interface Print {
	public void print();
	//public void show();
}

//工具类Uilt中
public Print getP(){
    return ()->{syso("我是黑白打印机")};
}

//测试类中
Print p = ()->{syso("我是彩色打印机");};
p.print();		//我是彩色打印机
Util.getP().print();//我是黑白打印机


//带参带返回值的函数式接口
public interface Print{
    public String get(int i);
}

//使用时
Print p = (int count)->{return "总共打印了"+count+"份文件";};
p.print();

练习:打印机接口中方法 带String brand int count 返回字符串 “xxx品牌的打印机打印了xx份文件‘

变量类型+运算符

选择+循环

数组

方法

面向对象 封装继承多态接口

API String Math Date

异常类

集合 有序集合 无序集合 Map集合

内部类-----》优化后写法

IO流—》流对象 和方法

多线程----》随机性

网络编程----》IO流

棋子

数据库-----》SQL语句 JDBC

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值