内部类
在一个类的内部定义另一个类-----------》成员内部类
在一个方法的内部定义另一个类--------》局部内部类
成员内部类
案例:
描述班级 班级类 班级名称 班级人数
描述学员 学生类 学员名称 学员性别
只能在班级类中 访问到学生类 其他类中 不准访问学生类
//外部类
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