内部类:
在一个类中定义另一个类. 举例:在类A中定义一个类B, 称类B是类A得内部类.
特点:内部类他都可以去访问外部类的成员,包括私有.
外部类的成员访问内部类的成员. 需要创建内部类对象,由内部类对象访问内部的
内部类的分类:
成员内部类:
位置:类内方法外的成员位置
被statica修饰的成员内部类被成为静态内部类
局部内部类:
位置:方法内
没有名字的局部内部类被称为匿名成员内部类:
成员内部类:
访问成员内部类(非静态)格式:
内部类名.外部类名 引用变量名 = 外部类对象.内部类对象;
package org.westos.Demo3;
//外部类
class Outer{
//成员内部类
class Inner{
public void show() {
System.out.println("我是成员内部类");
}
}
}
//测试类
public class OuterTest {
//主方法
public static void main(String[] args) {
Outer.Inner oi = new Outer().new Inner();//外部类成员内部类格式
oi.show();
}
}
成员内部类: 可以被private,statica关键字修饰;
1)被private修饰:为了保证数据的安全性.
被private修饰的成员内部类,不能直接进行访问.所以部能采用常规的
内部类名.外部类名 引用变量名 = 外部类对象.内部类对象这种方式去访问
解决方法: 通过调用外部类的一个方法,创建内部里对象,间接去访问内部类
package org.westos.Demo3;
//外部类
class Outer1 {
//
private class Inner1 {// 被私有化的成员内部类
public void show2() {
System.out.println("我是被私有的内部类");
}
}
// 外部类中的OuterMethod()方法,通过这个方法创建内部类对象.外部类间接的访问内部类
public void OuterMethod() {
Inner1 i = new Inner1();// 创建内部类对象
i.show2();
}
}
// 测试类
public class OuterTest1 {
// 主方法
public static void main(String[] args) {
// 创建内部类对象
Outer1 o = new Outer1();
o.OuterMethod();// 调用OuterMethod()方法
}
}
2)被static关键字修饰的成员内部类.被称为静态成员内部类.只是为了方便调用.
外部类要访问当前该内部类的成员方法的格式:
外部类名.内部类名 对象名 = new 外部类名.内部类名();
注: 在访问静态成员内部类时,可以将静态成员内部类当作外部类的一个成员.
package org.westos.Demo3;
//定义一个内部类
class Outer3 {
public int num1 = 1;
// public int num2 = 2;
public static int num2 = 2;
// 定义一个被static修饰的成员内部类(静态成员内部类)
public static class Inner3 {
public void show1() {// 静态只能访问静态,所以静态成员内部类只能访问外部类被static关键字修饰的成员
// System.out.println(num2);报错
System.out.println(num2);
}
public static void show2() {
// System.out.println(num2);报错
System.out.println(num2);// num2加上statica关键字之后,可以访问
}
}
}
// 测试类
public class OuterTest3 {
// 主方法
public static void main(String[] args) {
// 外部类访问静态内部类的格式
Outer3.Inner3 oi = new Outer3.Inner3();
oi.show1();
oi.show2();
}
}
局部内部类:
局部内部类里面的成员方法直接可以访问外部类的成员,包括私有.
注:局部内部类访问局部变量问题. 如果jdk是1.8版本一下
局部内部类访问局部变量的,该变量必须被final修饰
为什么必须被final修饰?
局部变量它随着方法调用而存在的,随着方法的调用完毕而消失就是因为现在有一个局部内部类,在外部类的 成员方法中在使用内部类对象(对象的创建完毕,不会立即被垃圾回收器回收掉),使用内部类对象还在调用内部类的 成员方法,就需要去访问局部变量,这个变量需要常驻内存(常量),它 必须被final修饰!
package org.westos.Demo3;
//定义一个外部类
class Outer4 {
private int num = 5;
// 定义一个Method方法
public void Method() {
// 局部变量
final int num1 = 6;
// 定义一个局部内部类Inner5
class Inner5 {
public void show3() {
System.out.println(num);
System.out.println(num1);// 如果在jdk 1.8版本一下,num1如果不被final修饰会报错
}
}
Inner5 i = new Inner5();// 创建局部内部类对象
i.show3();
}
}
// 测试类
public class OuterTest4 {
// 主方法
public static void main(String[] args) {
Outer4 o = new Outer4();// 创建外部类对象
o.Method();
}
}
匿名内部类:
它是内部类的简化版
前提:存在一个类或者接口(接口用多)
类:可以具体类/抽象类
格式:
new 类名/接口名(){
重写/实现一些方法()..
} ;
package org.westos.Demo3;
//定义一个接口
interface Inner1 {
public abstract void show1();
public abstract void show2();
}
// 定义一个外部类
class Outer5 {
// 外部类中的Method方法
public void Method() {
// new Inner1(){ //创建一个匿名内部类
// public void show1() {
// System.out.println("我是匿名内部类中的方法1");
//
// }
//
// @Override
// public void show2() {
// System.out.println("我是匿名内部类中的方法2");
//
// }
//
// }.show1(); //调用匿名内部类中的show1方法
//
// new Inner1(){
// public void show1() {
// System.out.println("我是匿名内部类中的方法1");
//
// }
//
// @Override
// public void show2() {
// System.out.println("我是匿名内部类中的方法2");
//
// }
//
// }.show2();; //调用匿名内部类中的方法2
// 如果接口中有多个方法,采用以上的调用方式特别麻烦.
// 下面是对这中方式的一个改进
Inner1 i = new Inner1() { // 创建一个匿名内部类
public void show1() {
System.out.println("我是匿名内部类中的方法1");
}
public void show2() {
System.out.println("我是匿名内部类中的方法2");
}
};
i.show1();// 调用匿名内部类中的方法1
i.show2();// 调用匿名内部类中的方法2
}
}
// 测试类
public class OuterTest5 {
// 主方法
public static void main(String[] args) {
Outer5 o = new Outer5();// 创建外部类对象
o.Method();
}
}