前几节课我们学习了java 的面向对象的封装继承多态。同时了解了对象的抽象模型:抽象类和接口。
截止目前java 的面向对象编程已经奠定了基础。
这节课我们学习java的类的其他形式:内部类。
今天的内容:
1、内部类是什么
2、内部类的分类
第一部分:内部类是什么
内部类就是在(外部)类内部再定义一个类,类名不需要和文件相同。
我们之前接触的类都是一个类一个文件,并且类名和文件名必须相同。今天学习的内部类就不符合这两个特点。
但是,内部类的其他结构和普通类基本相同,只不过定义在一个类的内部而已。
内部类只是一个编译时概念,通俗的讲,就是编写代码是感觉是内部的。等到实际编译完后,内部类其实是一个单独的文件。
假设有个外部类outer,他当中有个内部类inner,当这个文件编译成class文件后,就会产生outer.class和outer$inner.class两个文件。
有兴趣的可以去手动编译看看。
第二部分:内部的分类
内部类有如下几种形式:
1、成员内部类
成员内部类是外部类当中,方法外部,与成员变量和方法同级的类,不能使用static修饰。
特点:
成员内部类,就是作为外部类的成员,可以直接使用外部类的所有成员变量和成员方法,即使是private的。
外部类要访问内部类的所有成员变量/方法,则需要通过内部类的对象来获取。
成员内部类可以定义与外部类相同的成员变量和成员方法。
成员内部类不能声明static变量和方法。
初始化:Inner inner = new Outer().new Inner();也可以在外部类中定义公共方法来获取内部类。
我们看看如何定义一个成员内部类:
public class Test {//外部类
private String name;
void say(){}
class FieldClass{//成员内部类
private String name;
void say(){}
}
}
2、静态内部类
静态内部类与成员内部类的定义方式相同,都是外部类内部,成员变量和方法同级,但是使用static修饰。
特点:
静态内部类不能直接使用外部类的成员和方法。
外部类必须通过内部类的实例访问内部类。
静态内部类可以定义静态方法
静态内部类可以定义与外部类相同的成员和方法
静态内部类实例化时,不需要实例化外部类,但是需要外部类前缀。如Inner inner = new Outer.Inner();
我们看看例子:
public class Test {//外部类
private String name;
void say(){}
static class StaticClass{
private String name;
void say(){}
static void show(){
}
}
}
3、局部内部类
局部内部类是定义在方法或代码块内部的类,使用范围也在方法或代码块内。
我们来看看例子:
//方法
void say(){
//方法局部内部类
class Info{
int status;
String message;
Info(int status,String message){
this.status=status;
this.message=message;
}
}
//方法内部使用
Info info = new Info(0,"打印成功!");
}
4、匿名内部类
匿名内部类是不需要编写类名称的类。
严格的讲:匿名内部类是没有类名称的一种内部变量实现。内部类必须实现一个接口或继承一个类。
通俗的讲:匿名内部类是在实例化变量时,临时对父类或接口的一种实现方式。
特点:
内部类必须实现一个接口或继承一个类。
匿名内部类不能有构造方法。
匿名内部类不能定义任何静态成员、静态方法。
匿名内部类不能是public,protected,private,static。
只能创建匿名内部类的一个实例。
一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。
我们按照实现方式,将匿名内部类分为接口方式和继承方式。
使用例子来理解下:
1、继承类型。首先必须有个父类,才能使用。
//父类
public class Car {
public void drive(){
System.out.println("Driving a car!");
}
}
public static void main(String[] args) {
//实例化变量时,临时进行继承父类,实现父类的方法
Car car = new Car(){
public void drive() {
System.out.println("Driving another car!");
}
};
//匿名类重写父类的方法后,方法以及变为重写后的方法
car.drive();
}
2、接口类型。和继承的代码方式一样,只是实现的对象由父类变为接口
//接口
interface Vehicle {
public void drive();
}
public static void main(String[] args) {
//在实例化对象时,临时对接口进行实现
Vehicle v = new Vehicle(){
public void drive(){
System.out.println("Driving a car!");
}
};
//实现后的方法
v.drive();
}
以上就是今天的内容:
1、内部类是什么
2、内部类的分类
你学会了吗?