1.嵌套类和内部类
在类里面定义另一个类,这个类就叫嵌套类,嵌套类可以调用外部类的所有成员包含私有成员,但是外部类不能访问嵌套类中的成员。
sttatic修饰的变量、方法或嵌套类在没有创建对象的情况下可以通过类名直接访问,当然通过对象也可以进行访问,由于静态成员不能访问非静态成员,而非静态成员却可以通过类名.直接访问静态成员。
所以静态嵌套类就不能访问外部类的非静态成员了,所以很少使用静态嵌套类。
而非静态嵌套类就被广泛使用,俗称内部类。只能在外部类内创建内部类的实例对象,限制了内部类的作用域,在内部类的外部类之外的范围创建该内部类实力会产生错误报NosuchClassException。
2.内部类分类
2.1静态内部类
加了static的内部类,就是嵌套类,有两个特点:
①因为加了static所以可以通过类名直接访问,所以在创建静态内部类对象时,不需要先创建外部类对象了。
②因为static修饰的静态类成员不能访问非静态成员,所以静态内部类对象不能访问外部类的非静态成员。
③因为局部变量不能加static修饰词,所以不能在外部类的方法或类似for循环体的代码块中定义静态内部类。
2.2私有内部类
加了private修饰的内部类,就是私有内部类,相当于外部类的一个私有成员。
特点
①因为局部变量不能加private,所以不能在方法或者其他类似for循环体的代码块中定义私有内部类了。
2.3局部内部类
我们也可以在任何代码块的作用域内定义非静态的内部类把它看做一个局部变量,比如在方法或者for循环踢内定义嵌套类,称为局部内部类。
示例代码:
class Outer{
int a=6;
void test(){
for (int i = 0; i < 3; i++) {
class Inner{
void display(){
System.out.println("a="+a);
}
}
Inner inner = new Inner();
inner.display();
}
}
}
public class InnerClassDemo {
public static void main(String[] args) {
Outer outer = new Outer();
outer.test();
}
}
执行结果:
a=6
a=6
a=6
2.4匿名内部类
最常用的一种内部类,不需要类名,用来重写父类方法,常用于接口或者抽象类的实例化实现,new接口或者抽象类的匿名子类对象
Weapon w = new Weapon() {...};
(变量为父类类型,new的是子类对象,但由于子类没有类名,所以写成父类对象格式,()为父类构造器,后面接{父类重写方法,子类属性},最后要记得加“;”)
l 大括号是Weapon的匿名子类,其内可以重写父类Weapon的方法,并定义自己的属性
l new 新建匿名子类的对象
l 小括号 super()、super(参数),调用父类构造器
l 变量类型必须用父类型
示例代码:
//匿名内部类
public class AnonymousClass {
public static void main(String[] args) {
Humen humen = new Humen(){
private int b=20;
@Override
public void test1() {
System.out.println("重写父类接口中的抽象方法");
}
@Override
public int test2(int a) {
System.out.println("接口中变量默认都是公共的静态常量");
return 0;
}
};
humen.test1();
humen.test2(0);
Pig pig = new Pig(10){
@Override
void processDemo() {
System.out.println("重写父类抽象类中的抽象方法");
}};
pig.proDemo();
pig.processDemo();
System.out.println("定义匿名内部类的()是父类构造器,赋值i="+pig.i);
}
}
interface Humen{
int age=10;
void test1();
int test2(int a);
}
abstract class Pig{
int i;
public Pig(int i) {
this.i=i;
System.out.println("抽象方法有构造函数,但是接口没有构造函数");
}
void proDemo(){
System.out.println("这是个抽象类");
}
abstract void processDemo();
}
执行结果:
重写父类接口中的抽象方法
接口中变量默认都是公共的静态常量
抽象方法有构造函数,但是接口没有构造函数
这是个抽象类
重写父类抽象类中的抽象方法
定义匿名内部类的()是父类构造器,赋值i=10