笔记来自2019求知讲堂零基础Java入门编程视频教程 https://www.bilibili.com/video/av76235341
内部类
在java中,允许一个类定义在另一个类内部,这样的类叫内部类,后者称为外部类。
- 成员内部类:非静态内部类、静态内部类
- 匿名内部类
- 局部内部类
1.非静态内部类
//只是一个外部类Test3
public class Test3 {
//外部类的各种权限的属性
static int year;
int i;
public String s;
private boolean flag;
protected double d;
//外部类show方法
public void show() {
System.out.println("外部类show方法");
}
//这里定义一个内部类
class Inner1{
//内部类自己的属性
int i = 10;
int year = 1999;
//内部类show方法
public void show() {
System.out.println("内部类show方法");
}
//内部类的方法,为外部类属性赋值
public void setTest3Fileds() {
//内部类可以调用任何权限的外部类属性和方法,直接调用即可
d = 13.14;
s = "内部类";
flag = false;
show();
//若内部类和外部类属性方法重名,调用外部类属性和方法时需要加上完整类名.this.属性名,若是静态属性或方法,可以省略this
Test3.this.i = 1; //外部类属性i赋值
Test3.year = 2000; //外部类静态属性year赋值
Test3.this.show(); //调用外部类show方法
}
//内部类的方法,打印外部类属性的值
private void showTest3Fileds() {
System.out.println("内部类属性i=" + i);
System.out.println("外部类属性i=" + Test3.this.i);
System.out.println("内部类属性year=" + year);
System.out.println("外部类属性year=" + Test3.year);
System.out.println("外部类属性d=" + d);
System.out.println("外部类属性s=" + s);
System.out.println("外部类属性flag=" + flag);
}
}
//外部类方法,调用内部类赋值方法为属性赋值
public void setInfo() {
//外部类调用内部类方法必须新建一个内部类对象,然后再调用
//Inner1 inner1 = new Inner1();
//inner1.setTest3Fileds();
new Inner1().setTest3Fileds();
}
//外部类方法,调用内部类打印方法打印各属性的值
public void showInfo() {
new Inner1().showTest3Fileds();
}
//main方法,程序入口
public static void main(String[] args) {
//创建一个外部类对象t3
Test3 t3 = new Test3();
//调用其赋值和打印方法
t3.setInfo();
t3.showInfo();
//还可以直接创建内部类对象
Inner1 inner1 = new Test3().new Inner1();
//或
//Test3 t4 = new Test3();
//Inner1 inner1 = t4.new Inner1();
inner1.show();
}
}
从上面的例子中可以看出:
①内部类是其外部类的成员,所以可以访问外部类任何权限的其他成员变量和成员方法;
②外部类要访问内部类的成员,需要新建内部类对象,然后通过 内部类对象.成员 访问(或者访问的是static内部类中的static成员,可以使用 内部类.成员 访问)
③非静态内部类对象必须寄存在一个外部类对象中,如果有一个非静态内部类对象,那么一定存在对应的外部类对象。
此外:
④内部类不能与包含他的外部类名字相同
⑤非静态内部类不能有静态方法属性和静态初始化块
2.静态内部类
静态内部类可以看做是外部类的静态成员。
静态内部类可以访问外部类的静态成员,不能访问外部类的普通成员。
3.匿名内部类
先看下面的例子。test方法使用了接口A的run方法,因为run是抽象方法,所以必须要创建一个类AA实现接口并重写方法才能使用。
public class Test2 {
public void test(A a) {
a.run();
}
public static void main(String[] args) {
Test2 test2 = new Test2();
test2.test(new AA());
}
}
class AA implements A{
@Override
public void run() {
System.out.println("run");
}
}
interface A{
void run();
}
如果这个方法只需要使用一次,为此创建一个类略显繁琐,我们就可以在使用的时候创建一个匿名内部类。
匿名内部类适合只使用一次的类,它没有名字,不能被再次使用。
public class Test2 {
public void test(A a) {
a.run();
}
public static void main(String[] args) {
Test2 test2 = new Test2();
//匿名内部类
test2.test(new A() {
@Override
public void run() {
System.out.println("run");
}
});
}
}
interface A{
void run();
}
4.局部内部类
定义在方法内部的类,作用域仅限于本方法。
内部类的特性
-
作为类的成员
一个外部类可以有多个内部类
内部类可以声明为final的
和外部类不同,内部类可以声明为private和protected的
内部类也可以声明为static的,但不能再使用外部类非static的成员 -
作为类
内部类可以声明为abstract,可以被其他内部类继承
非static的内部类中不能声明static的成员
内部类的作用
内部类主要可以解决java不能多重继承的问题
现在有3个类A、B和C,类A想要同时获得类B和类C的方法并且重写,可以在类A内使用内部类分别继承B和C,并重写方法,变相的实现多重继承
class A{
//testB()、testC()方法,创建内部类对象并调用重写后的方法
public void testB(){
new InnerB().testB();
}
public void testC(){
new InnerC().testC();
}
//类A的内部类InnerB,继承类B,重写类B的testB方法
private class InnerB extends B{
@Override
public void testB() {
System.out.println("这是重写之后的testB方法");
}
}
//类A的内部类InnerC,继承类C,重写类C的testC方法
private class InnerC extends C{
@Override
public void testC() {
System.out.println("这是重写之后的testC方法");
}
}
}