内部类
概念
在类中定义的类,称为内部类
如:
class A{
class B{
}
public void test(){
class C{
}
test02(D);
MyInterface myInterface = D;
}
public void test02(MyInterface myInterface){
}
}
A: 被称为外部类
B: 被称为内部类
C: 也是内部类
D: 也可以定义内部类
分类
成员内部类
定义的位置: 类中方法以外
静态内部类
定义的位置: 类中方法以外
注意: 使用static修饰的成员内部类
局部内部类
定义的位置: 方法中
匿名内部类(*)
定义的位置: 值或实参中
成员内部类
定义位置:
在类中方法以外定义的类
语法:
访问权限修饰符 class 类名{
}
注意: 成员内部类中不能定义静态属性,静态方法,静态代码块
创建对象的方式:
内部类类名 对象名 = 外部类对象.new 内部类类名(实参列表);
注意:
在该内部类所在的外部类的普通方法中创建该内部类对象
可以使用this作为外部类对象
this.new 内部类类名(实参列表);
此时this可以忽略不写,所以可以简写为 new 内部类类名(实参列表);
当外部类属性与内部类属性重名时可以这么区分
外部类类名.this.属性名 -> 外部类属性
this.属性名 -> 内部类属性
方法重名时也一样
package demo01;
//成员内部类
public class OutClass {
private String str1 = "外部类属性";
private static String str2 = "外部类静态属性";
public void test01() {
System.out.println("外部类普通方法");
}
public static void test02() {
//在外部类静态方法中创建内部类对象
// InClass inClass = new InClass(); 写法错误, 静态方法中不能使用this
InClass inClass = new OutClass().new InClass();
System.out.println("外部类静态方法");
}
public void test03() {
//在外部类中创建内部类对象
InClass inClass = new InClass(); //此时应是this.new InClass(); this可省略不写
System.out.println("外部类方法");
}
public class InClass{
public String str = "内部类属性";
private String str1 = "内部类属性";
// private static String str2 = "内部类静态属性"; //不能定义
public InClass() {
}
public void test01() {
System.out.println("内部类普通方法");
}
// public static void test02() {} //不能定义
public void test(String str1) {
System.out.println(str1);
System.out.println(this.str1);
System.out.println(OutClass.this.str1);
this.test01();
OutClass.this.test01();
test02();
test03();
}
{}
// static {} //不能定义
}
}
package demo01;
import demo01.OutClass.InClass;
//测试类
public class Test {
public static void main(String[] args) {
OutClass outClass = new OutClass();
InClass inClass = outClass.new InClass();
System.out.println(inClass.str);
inClass.test01();
System.out.println("---------------");
inClass.test("局部变量");
}
}
运行结果
静态内部类
定义位置:
在类中方法以外定义的类
语法:
访问权限修饰符 static class 类名{
}
注意:
外部类可以定义的,该内部类都可以定义
创建对象:
内部类类名 对象名 = new 外部类类名.内部类类名(实参列表);
注意:
静态内部类中不能使用外部类非静态成员
package demo02;
//静态内部类
public class OutClass {
private String str1 = "外部类属性";
private static String str2 = "外部类静态属性";
public static class InClass{
private String str1 = "内部类属性";
private static String str2 = "内部类静态属性";
public InClass() {
}
public void test01() {
System.out.println(str1);
System.out.println(this.str1);
//静态内部类中不能使用外部类非静态成员
// System.out.println(OutClass.this.str1);
}
public static void test02() {
}
public void test03() {
System.out.println(str2);
System.out.println(OutClass.str2);
}
{}
static {}
}
}
package demo02;
import demo02.OutClass.InClass;
//测试类
public class Test {
public static void main(String[] args) {
InClass inClass = new OutClass.InClass();
inClass.test01();
inClass.test03();
}
}
运行结果
局部内部类
定义位置:
方法中
语法:
class 类名{
}
注意:
局部内部类中不能定义静态属性,静态方法,静态代码块
创建对象:
内部类类名 对象名 = new 内部类类名(实参列表);
注意:
只能在定义该内部类的方法中使用
使用范围: 必须在定义该类下,方法结束前
package demo03;
//局部内部类
public class OutClass {
public void test() {
class InClass{
private String str01 = "内部类属性";
// private static String str02 = "内部类静态属性"; //不能定义
public InClass() {
}
public void test01() {
}
// public static void test02() {} //不能定义
{}
// static {} //不能定义
}
InClass inClass = new InClass();
}
}
匿名内部类
定义的位置:
值或者实参中
语法:
父类名/父接口名 对象名 = new 父类名/父接口名(){
属性
方法
要重写的方法
}
特点:
一个匿名内部类只能创建一个对象
优点:
代码书写方便
缺点:
导致代码混乱,使其阅读性较差(新手)
案例: 不同按钮释放不同技能
Q: 沉默
W: 护盾
E: 转圈
R: 大宝剑
package demo04;
public interface OnClickListener {
void click();
}
package demo04;
public class Button {
private String name;
private OnClickListener listener;
public Button() {
}
public Button(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setListener(OnClickListener listener) {
this.listener = listener;
}
public void down() {
listener.click();
}
}
package demo04;
public class Test {
public static void main(String[] args) {
Button btn1 = new Button("Q");
Button btn2 = new Button("W");
Button btn3 = new Button("E");
Button btn4 = new Button("R");
btn1.setListener(new OnClickListener() {
@Override
public void click() {
System.out.println("释放沉默技能");
}
});
btn2.setListener(new OnClickListener() {
@Override
public void click() {
System.out.println("释放护盾技能");
}
});
btn3.setListener(new OnClickListener() {
@Override
public void click() {
System.out.println("释放转圈技能");
}
});
btn4.setListener(new OnClickListener() {
@Override
public void click() {
System.out.println("释放大宝剑技能");
}
});
btn1.down();
btn2.down();
btn3.down();
btn4.down();
}
}
运行结果
包装类
概念: 八个基本数据类型对应的引用数据类型
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
数据类型转换
将字符串转换为整数
int 转换后的数字 = Integer.parseInt(字符串);
将字符串转换为小数
double 转换后的数字 = Double.parseDouble(字符串);
将字符串转换为布尔
boolean 变量名 = Boolean.parseBoolean(字符串);
将各种类型转换为字符串
String 变量名 = "" + 要转换的数据;
自动拆箱与自动装箱
自动拆箱:
将基本数据类型的包装类对象转换为基本数据类型
自动装箱:
将基本数据类型再转换为对应的包装类的对象
数字缓冲区:
-128 ~ 127
常用类
Random
随机数
常用方法:
nextInt(最大值)
nextBoolean()
Scanner
键盘录入
常用方法:
next()
nextInt()
nextLong()
nextBoolean()
...
System
系统
属性:
in: 输入
out: 输出
err: 错误输出
常用方法:
static arraycopy(Object src, int srcPos, Object dest, int desPos, int length)
src: 要拷贝的数组
srcPos: 拷贝开始位置
dest: 目标数组
destPos: 从哪个位置开始写入
length: 拷贝数据的个数
注意: desPos + length <= dest.length
作用: 拷贝数组
static currentTimeMillis()
作用: 获取当前系统时间距离1970年1月1日00:00:00(格林威治时间)的时间差,单位毫秒
static gc()
作用: 手动调用垃圾回收机制
static exit(int status)
作用: 退出程序
status: 为0正常退出,非0非正常退出
Arrays
数组操作工具类
static sort(int[] a)
作用: 对数组进行排序
static toString(Object[] a)
作用: 将数组转换为特定格式的字符串