内部类
内部类它就是定义在类里面的类,但是根据在类中位置的不同,分为成员内部类,局部内部类。
成员内部类
成员内部类,写在类的成员位置
public class Outer{
private int num=10; //Outer类的成员变量
//成员内部类
class Inner{
int num=20;
public void show(){
int num=30;
System.out.println("Inner....show");
System.out.println(num); //30
System.out.println(this.num); //20
System.out.println(Outer.this.num); //10,Outer它的成员变量num
}
}
//静态的成员内部类
static class Inner2{
public void method(){
System.out.println("Inner2....method");
}
public static void method2(){
System.out.println("Inner2....method2");
}
}
}
public class Demo1{
public static void main(String[] args){
//创建Outer类中Inner类的对象
Outer.Inner inner=new Outer().new Inner(); //调用普通成员内部类的格式
inner.show():
//创建Outer类中Inner2的对象
Outer.Inner2 inner2=new Outer.Inner2(); //调用静态成员内部类的格式
inner2.method():
Outer.Inner2.method2();
}
}
局部内部类
局部内部类是写在方法中的类。 局部内部类只能在方法中使用,局限性太强,所以几乎不会用。
public class Outer{
public void method(){
//方法中的变量 - 局部变量
int num=10;
//方法中的类 - 局部内部类
class Inner{
public void show(){
System.out.println("Inner...show");
}
}
//创建Inner对象
Inner in=new Inner();
in.show();
}
}
匿名内部类
匿名内部类的本质,其实是一个抽象类、接口的子类对象。快捷键 Alt+Entry
1,使用匿名内部类的前提
需要有一个接口或者抽象类
2. 格式:
new 接口/抽象类(){
复写抽象方法
}
3. 本质:其实是一个抽象类、接口的子类对象。
Lambda表达式
Lambda表达式它可以简化匿名内部类的代码书写。Lambda表达式是 JDK1.8 之后才可以使用。快捷键 Alt+Entry
使用Lambda表达式使用步骤
1)必须要有一个函数式接口(只能有一个抽象方法的接口)
@FunctionalInterface用在接口上,用于检测是否符合函数式接口的规则
2)函数式接口一般作为方法的参数使用,调用方法时,传递Lambda表达式
Lambda表达式的格式
//标准格式
(Type1 param1,Type2 param2)->{ 方法体 return 结果; }
//省略数据类型
(param1,param2)->{ 方法体 return 结果; }
//如果{}中只有一条语句,可以省略大括号和return
(param1,param2)->结果
//如果()中参数只有一个,()可以省略
param1->结果
匿名内部类和Lambda表达式的区别
1.使用前提不一样
1)匿名内部类,有接口或者抽象类都可以
2)Lambda: 只能有接口的情况下使用(接口中必须只有一个抽象方法)
2.底层原理不一样
1)匿名内部类: 会生成字节码文件(.class文件)
2)Lambda: 不会生成字节码文件(.class文件)
老师教学生案例
- 需求背景介绍
假设有一个非常厉害的老师,有很多慕名而来的学生过来学习,有学生想学Java,老师就教这个学生学Java; 有学生想学UI,这个老师也能给学生教UI的课程; 有一天来了一批学生,老师就给这些学生开了一个班,一起来教这些学生学习。
有一天又来了一个学生,它想学挖掘机。
学Java的学生,要多学一门课程,学习JavaScript.
- 案例分析
分析案例中有哪些对象?
老师、学生
分析每一个对象有哪些功能?
老师:教一个学生、教一批学生
学生:学习
Java学生:学Java课程
UI学生:学UI的课程
分析有哪些接口?
Java学生要多学一门课程,可以看做是接口
public abstract class Student {
private String name;
private int age;
//篇幅有限,自己写构造方法、get和set方法
public abstract void study();
}
public interface JavaScript {
public void studyJs();
}
public class JavaStudent extends Student implements JavaScript{
public JavaStudent() {
}
public JavaStudent(String name, int age) {
super(name, age);
}
@Override
public void study() {
System.out.println("Java学生在学习JavaSE的课程");
}
@Override
public void studyJs() {
System.out.println("Java学习在学习Js课程");
}
}
public class UIStudent extends Student {
public UIStudent() {
}
public UIStudent(String name, int age) {
super(name, age);
}
@Override
public void study() {
System.out.println("UI学生在学习PS课程");
}
}
public class Teacher {
//教一个学生
public void teach(Student stu){
stu.study();
//判断stu是否是JavaStudent
if(stu instanceof JavaStudent){
((JavaStudent) stu).studyJs();
}
}
//教一批学生
public void teach(ArrayList<Student> list){
//遍历集合,获取每一个Student对象
for (int i = 0; i < list.size(); i++) {
Student stu = list.get(i);
teach(stu);
}
}
}
public class Demo7 {
public static void main(String[] args) {
Teacher t=new Teacher();
JavaStudent jstu=new JavaStudent("张三",20);
//教Java学生
t.teach(jstu);
UIStudent ustu=new UIStudent("李四",30);
//教UI学生
t.teach(ustu);
System.out.println("-----------------");
//创建一个集合,用于存储Student对象
ArrayList<Student> list=new ArrayList<>();
//创建两个JavaStudent对象
JavaStudent jstu1=new JavaStudent("张三",20);
JavaStudent jstu2=new JavaStudent("李四",30);
//添加到集合中
list.add(jstu1);
list.add(jstu2);
t.teach(list);
System.out.println("-------------------");
//让老师教一批学生
t.teach(new Student() {
@Override
public void study() {
System.out.println("学习开始学习挖掘机");
}
});
}
}