目录
引语:
内部类有四种:
1.实例内部类(不用static修饰)
2.静态内部类(用的很多)
3.局部内部类(基本不用)
4.匿名内部类
下面我们一个一个仔细来讲:
1.实例内部类
1.1概念:
1.没有被static修饰
2.定义在外部类的内部,外部类成员方法的外部。
1.2定义示例:
//外部类
class Out{
int a=10;
int b=20;
//内部类
class Inner{
int a=30;
int c=40;
public void method(){
System.out.println("内部类方法");
}
}
public void method(){
System.out.println("外部类方法");
}
}
可以看出,其实内部类和外部类,是相对的。
1.3实例内部类的创建和访问
//外部类
class OutClass {
int a = 10;
int b = 20;
//实例内部类
class InnerClass {
int a = 30;
int c = 40;
public void method() {
System.out.println("内部类方法");
}
}
public void method() {
System.out.println("外部类方法");
}
}
public class Test {
public static void main(String[] args) {
//要访问内部类成员,必须创建实例内部类对象
//因为实例内部类与其他外部类成员的定义位置相同
//因此创建实例内部类对象,必须借助外部类
//先创建外部类对象
OutClass outClass = new OutClass();
//内部类类型,用外部类名字申明 用外部类对象new一个内部类对象
OutClass.InnerClass innerClass = outClass.new InnerClass();
innerClass.method();
}
}
1.3.1方法总结:
1.先创建外部类对象
2.用外部类对象申明实例内部类的类型
3.用外部类对象new一个实例内部类
1.4实例内部类访问外部类的方法
不论是实例内部类还是外部类,访问类成员,都遵循就近原则:
如果不同名,当然访问类所直属的成员变量或方法,
如果同名,还是访问当前类所直属的成员变量或者方法。
示例:
//外部类
class OutClass {
int a = 10;
int b = 20;
//实例内部类
class InnerClass {
int a = 30;
int c = 40;
public void method() {
System.out.println("内部类方法");
System.out.println(a);
}
}
public void method() {
System.out.println("外部类方法");
System.out.println(a);
}
}
public class Test {
public static void main(String[] args) {
OutClass outClass = new OutClass();
OutClass.InnerClass innerClass = outClass.new InnerClass();
innerClass.method();
outClass.method();
}
}
执行结果:
分析:
很明显
实例内部类访问了,本类的同名方法method,外部类也一样。
实例内部类访问了,本类的字段a=30,外部类也一样,a=10
那么如果我们毅然决然要访问,外部类的同名方法或者变量怎么办呢?
其实很简单,我们只需要用 外部类类名.this.外部类成员方法或者字段
即可。
还是刚刚的例子,我们来看如何访问外部类成员:
//外部类
class OutClass {
int a = 10;
int b = 20;
//实例内部类
class InnerClass {
int a = 30;
int c = 40;
public void method() {
System.out.println("内部类方法");
//访问外部类的a
System.out.println(OutClass.this.a);
//调用外部类的方法
OutClass.this.method();
}
}
public void method() {
System.out.println("外部类方法");
System.out.println(a);
}
}
public class Test {
public static void main(String[] args) {
OutClass outClass = new OutClass();
OutClass.InnerClass innerClass = outClass.new InnerClass();
innerClass.method();
}
}
执行结果:
是不是很简单<^^>
1.5注意事项
1.外部类中的任何成员都可以在内部类中访问。
2.而外部类中,不能直接访问实例内部类中的成员,如果要访问必须创建实例内部类的对象才行。
第二点其实也好理解:
实例成员变量没有被static修饰,如果没有实例化,那么就不存在了,也就无法访问。
3.实例内部类所处位置,和外部类成员的位置相同,也受public、private等访问限定符修饰。
4.在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名 称.this.同名成员来访问(刚刚已经讲过)。
5.实例内部类对象必须在现有外部类对象的前提下,才能创建。
6.实例内部类中的非静态方法中,包含一个指向外部类对象的引用(其实就是this嘛)。
2.静态内部类(重要,经常用)
2.1概念以及定义方式:
就是在实例内部类的基础上多加了static的修饰
举个例子:
//外部类
class OutClass {
static int A = 10;
int b = 20;
//实例内部类
static class InnerClass {
//可以定义非静态成员
static int a = 30;
int c = 40;
public void method() {
System.out.println("静态内部类");
}
//可以定义静态成员
static int s=10;
public static void mmm(){
System.out.println("静态方法付,内部类汇总的");
}
//在静态内部类中只能访问外部类中的静态成员
int in=OutClass.A;
}
public void methodOut() {
System.out.println("外部类方法");
System.out.println(a);
}
}
注意:如果要更改外部类中的静态变量的值,要把语句写到内部类中的方法内,否则报错!
原因:
因为逻辑代码只能写在方法里面,类中和方法外,只能写成员方法和成员变量
2.2静态内部类对象的创建
静态内部类不依赖与对象,所以它的创建,不用实例化外部类。
示例:
2.3注意事项:
1.涉及到static修饰的方法,或这变量,只需要用类的名称去访问即可。
2.创建静态内部类的对象不需要创建外部类对象。
3.局部内部类(了解即可)
3.1概念及定义:
定义在外部类的方法体或者{}中,该种内部类只能在其定义的位置使用,一般使用的非常少,此处简单了解下语法 格式。
示例:
public class OutClass {
int a = 10;
public void method(){
int b = 10;
// 局部内部类:定义在方法体内部
// 不能被public、static等访问限定符修饰
class InnerClass{
public void methodInnerClass(){
System.out.println(a);
System.out.println(b);
}
}
// 只能在该方法体内部使用,其他位置都不能用
InnerClass innerClass = new InnerClass();
innerClass.methodInnerClass();
}
public static void main(String[] args) {
// OutClass.InnerClass innerClass = null; 编译失败
}
}
3.2 注意事项:
1. 局部内部类只能在所定义的方法体内部使用
2. 不能被public、static等修饰符修饰
3. 编译器也有自己独立的字节码文件,命名格式:外部类名字$数字内部类名字.class
4. 几乎不会使用
4.匿名内部类
4.1概念和定义方式
匿名,就是这个类没有自己的名字
内部类就是写在一个类的内部
示例1(用类实现):
格式:同名父类名 对象名 =new 同名父类名(){重写父类方法};
class Father {
public void method() {
System.out.println("Father");
}
}
public class Test {
public static void main(String[] args) {
//下面{}里的就是匿名内部类的成员方法了
//匿名内部类没有类名
Father father = new Father() { //用他的父类去接收匿名内部类实例化的对象(将会发生向上转型)
@Override
public void method() {//重写方法
System.out.println("匿名内部类");
}
};//记住要加分号
father.method();//调用此方法时就会发生多态
}
}
示例2(接口实现):
格式:同名接口 对象名=new 同名接口(){ 重写接口中的方法 };
interface Itest {
public abstract void test();
}
public class Test {
public static void main(String[] args) {
Itest inter = new Itest() {
@Override
public void test() {
System.out.println("接口实现的匿名内部类");
}
};
}
}
4.2应用场景
匿名内部类省略了子类的创建、实例化、继承 让代码变得简洁,
我们可以直接用一个父类或者接口得到我们想要的东西。
========================================================
完