在 Java 中什么是内部类如何定义?
简单来讲其实就是在一个类中定义一个类
- 成员内部类
- 静态内部类
- 局部内部类
- 匿名内部类
- 成员内部类
外部类中不能直接访问内部类中的成员
内部内中可以直接访问外部类中的成员
class Outer { // 外部类
private int num = 100;
private int age = 30;
public int getAge() { return this.age; }
public void setAge(int age) { this.age = age; }
public void outerMethod(){
System.out.println("Outer num = " + num);
// 外部类如果需要访问内部类成员,
// 必须使用对象的方式访问
Inner inner = new Inner();
// 使用对象可以访问内部类的任意成员
System.out.println("outerMethod.Inner.num = " + inner.num);
}
// 成员内部类
class Inner {
private int num = 1000;
public int getNum(){ return this.num; }
public int setNum(int num){ return this.num = num; }
public void innerMethod(){
// 如果想要访问外部类的成员,
// 只能通过外部类的方式访问
Outer outer = new Outer();
// 在内部类中可以直接访问外部类的任意成员
System.out.println(outer.getAge());
}
}
}
- 静态内部类
内部类中不能直接访问外部类中的成员
外部类中也不能直接访问内部类中的成员
访问静态成员的方式:类名.静态成员名
创建静态内部类的方式:外部类名.内部类名 对象名 = new 外部类名.内部类名()
class StaticOuter{ // 普通外部类
private int num = 10;
private int age = 20;
public int getAge() { return this.age; }
public void setAge(int age) { this.age = age; }
// 静态内部类
static class Inner {
private int num = 100;
public int getNum() { return this.num; }
public void setNum(int num) { this.num = num; }
public void innerMethod(){
System.out.println("num = " + num);
// 不能直接访问外部类中成员
// System.out.println("age = " + age);
// System.out.println("age = " + StaticOuter.age);
}
}
}
- 局部内部类
内部类被定义在方法体
一旦方法体中定义了内部类, 那么该方法的参数被默认添加 final 关键字进行修饰
参数的值不允许被修改(在该方法体中的任意位置都不能进行修改)
并且只能在方法体中创建局部内部类的对象
例如:
public class TestLocalInner {
public static void main(String[] args) {
LocalOuter outer = new LocalOuter();
outer.test(123);
}
}
class LocalOuter{ // 普通外部类
private int n = 1000;
private int age = 20;
public int getAge(){ return this.age; }
public void setAge(int age){ this.age = age; }
public void test(int i){ // i = 123 (final i)
// 局部内部类(只能被定义在方法体中)
class Inner{
private int num = 100;
private int age = 30;
public int getNum(){ return this.num; }
public void setNum(int num){ this.num = num; }
public void innerMethod(){
System.out.println("num = " + num); // 100
System.out.println("age = " + age); // 30
System.out.println("n = " + n); // 1000
// i += 10; // Error: 不能直接修改参数的值
System.out.println("Prameter i = " + i);
}
}
// 只能在方法体中创建局部内部类的对象
Inner inner = new Inner();
inner.innerMethod();
}
}
- 匿名内部类
没有名字的类称之为匿名类
父类类型 对象名 = new 父类(){
重写父类方法
}
public class TestAnomumousInner {
public static void main(String[] args) {
// 匿名内部类
Usb mouse = new Usb(){
public void service(){
System.out.println("test mouse service...");
}
};
mouse.service();
keyboard.service();
Usb upan = new Usb(){
public void service(){}
};
}
}
interface Usb{
void service();
实际上匿名内部类在编译时由编译器自动命名
– 命名方式: 在当前类名称后面 + $ + Number
– Number是从1开始进行递增
建议少使用匿名内部类:
- 匿名内部类中必须实现接口中的所有的抽象方法
- 匿名内部类每次都需要进行方法重写(容易产生冗余代码)
- 使用场景:
- 当一个接口只有一个抽象方法时,可以考虑使用匿名内部类的方式
- 该抽象方法每次实现的功能都不相同
以上就是咋们Java里的内部类
平常成员内部类和匿名内部类用得相对于来说多一点
接下来给大家简单介绍一下常用类
常用类
Object:
Object是所有类的超类
比如:如果一个类没有指定继承的父类,那么就会默认继承Object
如果要得到哈希值:
重写hashCode()
如果要比较对象是否相等
重写equals(Object obj)
如果要得到对象的详细信息
重写toString()
包装类
基本数据类型不能按照面向对象的思想去考虑问题
在Java中,对八种基本数据类型提供了对应的八个包装类
基本类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
boolean | Boolean |
char | Character |
将基本数据类型转换为引用数据类型
Integer i = new Integer(123); // 手动装箱
int n = i.intValue(); // 手动拆箱
Integer i2 = 1000; // 自动装箱
int j = i2; // 自动拆箱
装箱:
将基本数据类型转换成为包装类(引用类型)
拆箱:
将引用类型(包装类)转换成为基本类型