课程来源 中软国际java培训班
一、非静态内部类
相当于一个外部类的成员变量,从语义上讲,与外部类已有成员平级
使用的话必须new一个外部类的对象,再通过这个对象生成内部类对象
class OuterClass{
private int outerData;
public OuterClass(int outerData) {
this.outerData = outerData;
}
public void showOuterData(){
System.out.println("outerData = " + outerData);
}
//外部类不能访问内部类属性或方法
//非静态内部类:在外部类的内部,定义了一个“非静态的内部类”
//注意:对于内部类来讲,最前面的访问级别修饰符,可以使用4种中的任意一种
//关系类似寄生虫,肚子里的蛔虫
public class InnerClass{
private int innerData;
public InnerClass(int innerData) {
this.innerData = innerData;
}
public void showInnerData(){
System.out.println("innerData = " + innerData);
}
//在非静态内部类中,可以直接访问外部类的属性
public void innerShowOuterData(){
System.out.println("在内部类中,打印外部类属性的值:outerData = " + outerData);
// //内部类访问外部类属性、方法的本质语法理解:
// OuterClass.this.showOuterData();
}
//在非静态内部类中,也可以直接调用外部类的方法
public void innerCallOuterMethod(){
System.out.println("内部类中调用外部类的方法:");
showOuterData();
}
}
}
public class class1 {
public static void main(String[] args) {
//创建外部类对象
OuterClass outerObj = new OuterClass(100);
outerObj.showOuterData();
//创建内部类对象,首先必须外部类对象存在,在其基础上才能创造内部类对象
// OuterClass.InnerClass innerObj = new OuterClass.InnerClass(200);//不能直接通过内部类构造方法创建对象
OuterClass.InnerClass innerObj = outerObj.new InnerClass(200);//“借助”外部类对象创建内部类对象
innerObj.showInnerData();//内部类对象调用外部类属性
innerObj.innerShowOuterData();//内部类对象调用外部类属性
innerObj.innerCallOuterMethod();//内部类对象调用外部类方法
}
}
二、静态内部类
所有成员都是静态的,静态内部类智能访问外部类的静态成员。
静态内部类和非静态内部类的区别
非静态内部类本质上是外部类的一个成员,所以可以在内部类中使用 this 访问外部类的成员。【有从属关系】
静态内部类只是“嵌套定义”在外部类的一个类,跟外部类成员没有成员从属关系。所以在静态内部类中不能使用外部类的 this 指针,智能访问外部类的静态成员。【相互独立】
三、方法内部类
public class class3 {
//当前类在方法的内部定义,它的作用只在当前代码块中有效(局部内部类)
public static void main(String[] args) {
class MyMath{
private int a;
private int b;
public MyMath(int a,int b){
this.a = a;
this.b = b;
}
public int sum(){
return a+b;
}
}
MyMath myMath = new MyMath(1,2);
System.out.println("1 + 2 = " + myMath.sum());
}
public static void otherMethod(){
//超出 MyMath类的作用范围,下面代码出错,找不到MyMath类
// MyMath myMath = new MyMath(1,2);
}
}
四、匿名内部类
以下四类例子中main函数会调用的其他类:
class Student implements Driver {
private String name;
private int age;
public Student(String name,int age){
this.name = name;
this.age = age;
}
@Override
public void driverCar() {
System.out.println(name+"有驾照,会开车。");
}
}
class Teacher implements Driver {
private String name;
private int age;
public Teacher (String name,int age){
this.name = name;
this.age = age;
}
@Override
public void driverCar() {
System.out.println(name+"有驾照,会开车。");
}
}
class Father {
public void fatherMethod(){
System.out.println("这是父类中的方法!");
}
}
1. 传统:使用接口类型,指向实现类的对象
public static void main(String[] args) {
Driver driver1 = new Student("张三",25);
Driver driver2 = new Teacher("老马",40);
driver1.driverCar();
driver2.driverCar();
}
2. 匿名内部类用法
语法格式如下:
Driver driver3 = new Driver() {
@Override
public void driverCar() {
System.out.println("我是工人,我会开车");
}
};
Driver driver4 = new Driver() {
@Override
public void driverCar() {
System.out.println("我是程序员,我也会开车");
}
};
3. 匿名内部类,可以原地继承普通类、抽象类作为父亲
这条其实没啥意义,因为出去就调用不到了。
//一般不要在匿名内部类中,编写子类的特殊新方法,因为父类引用调用不到(写了也没意义)
Father obj1 = new Father(){
//一般请不要在匿名内部类中,编写子类的特殊新方法,因为父类引用调用不到!!!
public void sonMethod(){
System.out.println("匿名内部类自身的方法!");
}
@Override
public void fatherMethod() {
System.out.println("子类覆盖了父类的方法!");
}
};
obj1.fatherMethod();
// obj1.sonMethod();//匿名内部类无法访问自身的特殊属性、方法了