内部类:类中定义类就是内部类
- 成员内部类:
内部类定义在外部类的成员位置
成员:可以使用成员修饰符:public、static ……
类:可以继承类,可以实现接口 - 注意:
1、内部类中可以直接使用外部类中的所有的内容,包括私有的
2、内部类中不可以直接定义静态的内容,除了静态的常量,静态的内容要定义在静态内部类当中
3、创建成员内部类的对象要依赖于外部类对象 - 同名变量的区分:
public class Outer{
int a=5;
//成员内部类
public class Inner{
int a=10;
public void haha(){
int a=15;
System.out.println(a); //15 就近原则
System.out.println(this.a); //10
System.out.println(Outer.this.a); //5
Outer out=new Outer();
System.out.println(out.a);
}
}
}
当外部类、成员内部类、内部类方法中存在同名变量时。在内部类方法中调用内部类同名变量使用this关键字,调用外部类同名变量使用外部类名.this.变量名或者创建外部类对象调用。
- 静态内部类
1、静态内部类可以定义静态的内容可以定义成员的内容
2、在静态内部类中使用外部类中的非静态的内容,要通过外部类的对象去使用
3、在外部类中可以通过类名使用静态内部类中的静态内容,需要通过对象使用静态内部类中的成员内容
4、在其他类中可以通过外部类名.静态内部类名.静态内容使用静态内部类中的静态内容
new 外部类.静态内容类() 创建静态内部类的对象使用静态内部类中的成员
public class StaticInner {
public static void main(String[] args) {
System.out.println(Outer04.Inner.id);
Outer04.Inner.hehe();
Outer04.Inner in=new Outer04.Inner();
in.haha();
}
}
class Outer04{
private int a=5;
private static int b=10;
//静态内部类
static class Inner{
//静态内部类中的静态变量
static int id=0;
//静态内部类中的成员变量
String name="徐民生";
//静态内部类中的静态方法
static void hehe(){
System.out.println(id);
Inner in=new Inner();
System.out.println(in.name);
System.out.println(b);
Outer04 s=new Outer04();
System.out.println(s.a);
}
//静态内部类中的成员方法
void haha(){
System.out.println(id);
System.out.println(name);
Outer04 s=new Outer04();
System.out.println(b);
System.out.println(s.a);
}
}
//外部类中的成员方法
void outer(){
System.out.println(Inner.id);
Inner in=new Inner();
System.out.println(in.name);
Inner.hehe();
in.haha();
}
}
- 局部内部类:方法中定义内部类
1、局部内部类不可以使用成员修饰符修饰(比如:public、static…不包括final)
2、只能在当前定义局部内部类的方法中可以通过内部类的对象使用内部类中的成员,通过类可以使用静态
3、局部内部类所再的方法的参数,在jdk1.8之后默认,1.7之前需要显示定义
//外部类
class Outer05{
String name="李四";
//成员方法
void test(final int args){
int a=5; //局部变量
//局部内部类
class Inner{
static final int age=18;
int height=185;
void inner(){
System.out.println(a);
System.out.println(age);
System.out.println(name);
System.out.println(args);
//args=15;
}
}
//在当前方法中使用局部内部类中的内容
System.out.println(Inner.age);
Inner in=new Inner();
in.inner();
System.out.println(in.height);
}
void outer(){
test(4);
/*Inner in=new Inner();
in.inner();*/
}
}
- 私有内部类:
私有内部类中可以使用外部类中所有的内容,包括私有的
在外部类中使用私有内部类中的私有内容只能通过对象
私有内部类的内容,其他类不能使用
class Outer03{
private int a=10;
private static int b=20;
//私有内部类
private class Inner{
private int c=30;
private void haha(){
System.out.println(c);
System.out.println(a);
System.out.println(b);
}
}
//外部类的成员方法
public void outer(){
Inner in=new Inner();
System.out.println(in.c);
in.haha();
}
}
- 匿名内部类:没有名字的内部类
作用:简化没有独自作用(功能)的实现(子类)
语法:
new 类名(){类体}
new 接口名(){类体}
Lambda表达式
目标:简化匿名内部类
语法: ()->{}
() :重写的抽象方法的参数列表
-> :箭头符号,箭头函数,Lambda符号
{} :重写的抽象方法的方法体
使用前提:函数式接口
函数式接口:只有一个抽象方法的接口就是函数式接口
强制检查是否为函数式接口 :@FunctionalInterface
- 写法:
1、常规写法
2、如果方法的语句体只有1句,前后的{}可以省略
3、如果存在参数,参数的数据类型可以省略
4、如果存在参数,并且参数只有一个前后的()可以省略
5、有返回值类型的方法,如果方法体语句只有1句,并且是return语句的时候,这时前后{},包括return都可以省略
//Lambda表达式写法1:
Code c=()->{
System.out.println("边敲代码边哄女朋友");
};
//2:如果方法的语句体只有1句,前后的{}可以省略
Code c=()->System.out.println("边敲代码边哄女朋友");
//写法3: 如果存在参数,参数的数据类型可以省略
Code c=(i,m)->System.out.println("边敲代码边哄女朋友"+i+"次");
//写法4:如果存在参数,并且参数只有一个前后的()可以省略
Code c= i ->{
System.out.println("边敲代码边哄女朋友"+i+"次");
return -1;
};
System.out.println(c.code(100));
//写法5: 有返回值类型的方法,如果方法体语句只有1句,并且是return语句的时候,这时前后{},包括return都可以省略
Code c= str -> str.length();
数组: [],相同数据类型的有序集合
-
数组的特点:
1、数组是引用数据类型
2、数组是定长的,长度一旦确定不可改变
3、数组中所有数据的数据类型保持一致
4、数组中的数据存在顺序(索引:从0开始) -
数组的声明方式:
- 数据类型[] 数组名;
数据类型:可以是基本数据类型|引用数据类型
数据类型的作用:规定数组中所有数据的数据类型 - 数据类型 数组名[]; --不推荐使用
- 数据类型[] 数组名;
-
数组的初始化:
1、动态初始化:先创建后赋值
数据类型[] 数组名 = new 数据类型[长度];
数组中的数据如果不赋值有默认值 String–null,int–0,double–0.0 ,char–’ ',boolean–false
2、静态初始化:创建的同时赋值
数据类型[] 数组名 =new 数据类型[]{值1,值2,值3…};
数据类型[] 数组名 ={值1,值2,值3…}; --推荐 -
操作(获取|修改)数组中的数据:
通过索引操作 数组名[索引|下标] -
数组的长度:
数组名.length -
*数组的遍历:
1)普通for循环:可以获取可以修改,因为是操作索引(位置)
2)增强for循环|for…each :只能获取每一个数据,不能修改
for(数据类型 变量名: 数组名|容器名){} -
使用数组时常见的异常:
1、NullPointerException 空指针异常
对象指向为null,根据这个对象做一些操作,可能对出现空指针
2、ArrayIndexOutOfBoundsException 数组索引越界异常
1)索引为负数
2)索引超出最大范围 -
可变参数:数据类型相同的0~多个参数
1、使用…表示可变参数
2、编译器会自动为可变参数隐式创建一个数组,通过操作数组的方式使用可变参数
3、可变参数必须放在参数列表的最后位置
4、使用Object类型可使可变参数传入Object类型的值,如:int类型,String类型等(利用了多态)
public class ParaDemo {
public static void main(String[] args) {
getSum(1,2,3,4,5,6);
test(1,"","",1,false);
}
//至少接收一个参数,可以接收多个参数
public static void test(int name,Object ...arr){
System.out.println(name);
for(Object n:arr){
System.out.println(n);
}
}
//计算int类型参数的和
public static void getSum(int ...i){
System.out.println("可变参数方法");
System.out.println(i);
int sum=0;
for(int n:i){
sum+=n;
}
System.out.println(sum);
}
}