概述
10.java内部类
包含在类中的内就是内部类,包含内部类的类是外部类。
内部类有四种:成员内部类,方法内部类,静态嵌套类,匿名内部类
1.成员内部类
相当于java类中的成员变量基本结构:
public class TestClass{
public class InnerClass {
}
}
内部类编译后会形成一个新的字节码文件【外部类类名$内部类类型.class】
1.1成员内部类用法
(1)成员内部类可以使用任意的访问限制修饰符;
public class TestClass {
//成员内部类可以使用任意的访问限制修饰符
public class InnerClass{ }
protected class InnerClass1{ }
class InnerClass2{ }
private class InnerClass3{ }
}
(2)成员内部类可以有实例变量、实例方法、构造方法,不能有静态元素
代码测试:
public class TestClass {
//成员内部类
public class InnerClass{
//成员内部类可以有实例变量、实例方法、构造方法,不能有静态元素
int id=10;//成员内部类实例变量
//static String name="zhangsan";//报错,成员内部类不能有静态变量
public void Innermethod(){
System.out.println("成员内部类的实例方法");
}
public InnerClass(){
System.out.println("成员内部类的构造方法");
}
//public static void staticInnermethod(){}//报错,成员内部类不能有静态方法
}
}
(3)成员内部类中的构造方法可以访问其他的构造方法【new】,可以访问实例变量/方法【对象.实例变量/方法,this.实例变量/方法,可以省略对象/this】
(4)成员内部类中的实例方法可以访问构造方法【new】,可以访问实例变量/方法【对象.实例变量/方法,this.实例变量/方法,可以省略对象/this】。
(5)成员内部类中的构造方法可以访问外内部类的构造方法,实例方法/变量,类方法/变量。
(6)成员内部类中的实例方法可以访问外部类的构造方法,实例方法/变量,类方法/变量。
(7)外内部类中的构造方法/实例法可以访问成员内部类的构造方法,实例方法/变量,外内部类中的类方法不能访问成员内部类。
外部类访问内部内时,用.this和省略都会错,只能对象访问。
外内部类中的类方法,new内部类对象报错
(8)其他类中是可以访问成员内部类的,需要依赖外部类对象【new外部类类名().new 静态嵌套类名()】,注意访问限制修饰符。
也是不能用this.和省略
public class TestClass {
public String name="wuwei";//外部类实例变量
public static String lsp="sss";//外部类静态成员变量
public void outMethod(){
System.out.println("外部类的实例方法");
new InnerClass();
new InnerClass().id=1001;
new InnerClass().Innermethod1();
//InnerClass.this.id=1000;报错
//id=1000;报错
}
public static void staticOutMethod(){
System.out.println("外部类的静态方法");
//new InnerClass();报错
}
public TestClass(){
System.out.println("外部类的构造方法");
new InnerClass();
new InnerClass().id=1001;
new InnerClass().Innermethod1();
//InnerClass.this.id=1000;报错
//id=1000;报错
}
//成员内部类
public class InnerClass{
//成员内部类可以有实例变量、实例方法、构造方法,不能有静态元素
int id=10;//成员内部类实例变量
//static String name="zhangsan";//报错,成员内部类不能有静态变量
public void Innermethod1(){
System.out.println("成员内部类的实例方法1");
new TestClass();//访问外部类
new TestClass().name="zj";//访问外部类实例变量方法1
TestClass.this.name="zj";//访问外部类实例变量方法2
new TestClass().lsp="sss";//访问外部类静态变量
TestClass.this.staticOutMethod();
TestClass.this.lsp="sss";
new TestClass().staticOutMethod();//访问外部类静态方法
//TestClass.this表示外部类这个当前类
new TestClass().outMethod();//访问外部类实例方法,方法1
TestClass.this.outMethod();//访问外部类实例方法,方法2
//还可以省略
outMethod();
name="zj";
}
public void Innermethod2(){
System.out.println("成员内部类的实例方法2");
InnerClass ic=new InnerClass("lisi");//访问其他构造方法,内部类的对象
ic.id=11;//访问实例变量方式1
this.id=12;//访问实例变量方式2
id=13;//访问实例变量方式3,this和对象可以省略,
ic.Innermethod1();//访问实例方法1
this.Innermethod1();//访问实例方法2
Innermethod1();//访问实例方法3
}
public InnerClass(){
System.out.println("成员内部类的构造方法");
InnerClass ic=new InnerClass("lisi");//访问其他构造方法,内部类的对象
ic.id=11;//访问实例变量方式1
this.id=12;//访问实例变量方式2
id=13;//访问实例变量方式3,this和对象可以省略,
ic.Innermethod1();//访问实例方法1
this.Innermethod1();//访问实例方法2
Innermethod1();//访问实例方法3
}
//public static void staticInnermethod(){}//报错,成员内部类不能有静态方法
public InnerClass(String name){
System.out.println("成员内部类有参数的构造方法");
InnerClass ic1=new InnerClass();//访问其他构造方法,内部类的对象
ic1.id=11;//访问实例变量方式1
this.id=12;//访问实例变量方式2
id=13;//访问实例变量方式3,this和对象可以省略,
ic1.Innermethod1();//访问实例方法1
this.Innermethod1();//访问实例方法2
Innermethod1();//访问实例方法3
new TestClass();//访问外部类
new TestClass().name="zj";//访问外部类实例变量方法1
TestClass.this.name="zj";//访问外部类实例变量方法2
new TestClass().lsp="sss";//访问外部类静态变量
TestClass.this.staticOutMethod();
TestClass.this.lsp="sss";
new TestClass().staticOutMethod();//访问外部类静态方法
//TestClass.this表示外部类这个当前类
new TestClass().outMethod();//访问外部类实例方法,方法1
TestClass.this.outMethod();//访问外部类实例方法,方法2
//还可以省略
outMethod();
name="zj";
}
}
}
public class OtherClass {
public void otherMethod(){
System.out.println("其他类的实例方法");
//试着访问另一个类里面的内部类变量和方法
//先访问外部类,再去内部类
new TestClass();
new TestClass().new InnerClass();
//相当于先new外部类,TestClass tc=new TestClass();
//在new内部类,TestClass.InnerClass tci=tc.new InnerClass();
TestClass tc=new TestClass();
TestClass.InnerClass tci=tc.new InnerClass();
tci.id=999;
tci.Innermethod1();
}
public static void staticOtherMethod(){
System.out.println("其他类的静态方法");
new TestClass();
new TestClass().new InnerClass();
//相当于先new外部类,TestClass tc=new TestClass();
//在new内部类,TestClass.InnerClass tci=tc.new InnerClass();
TestClass tc=new TestClass();
TestClass.InnerClass tci=tc.new InnerClass();
tci.id=999;
tci.Innermethod1();
}
public OtherClass(){
System.out.println("其他类的构造方法");
new TestClass();
new TestClass().new InnerClass();
//相当于先new外部类,TestClass tc=new TestClass();
//在new内部类,TestClass.InnerClass tci=tc.new InnerClass();
TestClass tc=new TestClass();
TestClass.InnerClass tci=tc.new InnerClass();
tci.id=999;
tci.Innermethod1();
// Innermethod1();不能省略
// id=999;
}
}
2.方法内部类
定义在方法中的类,相当于局部变量
基本格式:
public class TestClass {
public TestClass(){
//构造方法里面的内部类
class InnerClass{
}
}
}
2.1 方法内部类用法
(1)方法内部类(相当于局部变量),不能使用任何访问限制修饰符;
(2)方法内部类可以有实例变量/方法,构造方法,不能有静态元素;
(3)方法内部类可以访问本类的实例变量、实例方法、构造方法。【this/对象,也可以省略】;
(4)方法内部类可以访问本方法的局部变量,直接变量名称访问。
方法内部类访问本方法的局部变量时,方法内部类会默认是有final修饰符修饰本方法中的局部变量,final修饰的不能改值,局部变量也没有对象,不能创建对象。
(5)外部类是不能访问到方法内部类。
因为方法内部类相当于本方法中的局部变量,局部变量超出本方法访问不到。
例:
public class TestClass {
int niu=222;//外部类实例变量
static String ok="hao";//外部类类变量
public TestClass(){
System.out.println("外部类的构造方法");
class InnerClass{
//构造方法里面的内部类
}
}
public void shiMethod(){
System.out.println("外部类的实例方法");
}
public static void staticShiMethod(){
System.out.println("外部类的静态方法");
}
public void TestClass1(){
int number=88;//本方法中的局部变量
//实例方法里面的内部类
class InnerClass{
int id=988;//实例变量
//static String name="hhh";报错
public void method1(){
System.out.println("方法内部类里面的实例方法");
new InnerClass();
new InnerClass().id=222;
new InnerClass().method1();
new InnerClass("ddd");
this.id=33;
this.method1();
id=33;
method1();
//访问方法内部类外面的本方法中的局部变量
//this.number=999; 错误,局部变量默认是final修饰的,不能改值
//局部变量也没有对象,不能创建对象
//所以直接变量名称访问
System.out.println(number);
}
public InnerClass(){
System.out.println("方法内部类里面的构造方法1");
new InnerClass();
new InnerClass().id=222;
new InnerClass().method1();
new InnerClass("ddd");
this.id=33;
this.method1();
id=33;
method1();
}
public InnerClass(String name){
System.out.println("方法内部类里面的构造方法2");
}
}
}
public static void TestClass2(){
//静态方法里面的内部类
class InnerClass{
//方法内部类可以访问外部类的构造方法,实例方法/变量,类方法/变量
public void method1(){
new TestClass();
new TestClass().shiMethod();
new TestClass().niu=22;
new TestClass().staticShiMethod();
new TestClass().ok="ss";
}
}
}
}
3.静态嵌套类
相当于是java类中的静态变量
格式:
public class TestClass {
public static class InnerClass{
}
}
(1)静态嵌套类中可以有构造方法,实例变量/方法,类变量/方法;
(2)静态嵌套类中构造方法/实例方法可以访问本静态嵌套类中的构造方法,实例变量/方法,类变量/方法;
(3)静态内部类中的类方法可以访问本静态嵌套类中的构造方法,实例变量/方法【只能对象】,类变量/方法;
(4)静态内部类中的构造方法/实例方法/类方法可以访问外部类的构造方法,实例变量/方法【只能对象】,类变量/方法;
(5)静态嵌套类中不能有this.
(6)外部类的构造方法/实例方法/类方法可以访问静态内部类中构造方法,实例变量/方法【只能对象】,类变量/方法;
(7)其他类中可以访问静态嵌套类【new外部类类名.静态嵌套类名()】。注意访问限制修饰符。
例:
public class TestClass {
public static int id=5;
public static int num=7;
public void method1(){
}
public static class InnerClass{
//静态内部类的实例变量
int id=23;
//静态内部类的静态成员变量
static int num=20;
//静态内部类的构造方法
public InnerClass(){
new InnerClass();
new InnerClass().id=1;
new InnerClass().num=1;
new InnerClass().method();
new InnerClass().staticMethod();
}
//静态内部类的实例方法
public void method(){
new InnerClass();
new InnerClass().id=1;
new InnerClass().num=1;
new InnerClass().staticMethod();
}
//静态内部类的静态方法
public static void staticMethod(){
new InnerClass();
new InnerClass().id=1;
new InnerClass().num=1;
new InnerClass().method();
new TestClass();
new TestClass().id=2;
new TestClass().num=2;
new TestClass().method1();
//this.
}
}
}
public class OtherClass {
public void method(){
//其他类中可以访问静态嵌套类【new 外部类类名.静态嵌套类名()】
new TestClass.InnerClass();
}
}
4.匿名内部类
没有名字的java类,在不用创建出新类的情况下,构建出当前类的子类,构建的这个子类没有名字,所以叫匿名内部类。
基本格式:
public class Person {
public void method(){
System.out.println("person的方法");
}
}
测试类:
public class Main {
public static void main(String[] args) {
//不创建新类的情况下构建子类,叫匿名内部类
Person per=new Person(){
public void method(){
System.out.println("person的方法重写");
}
};
per.method();
}
}
上述蓝色标记就是匿名内部类,就相当于Person类的子类,只是没有名字。
4.1 继承式的匿名内部类
这个匿名内部类的作用是在不创建新类的情况下创建父类的子类,实现继承关系。
例:
//抽象类
public abstract class Person {
//抽象方法
public abstract void method();
}
//普通类
public class PuTong{
//实例方法参数是抽象对象
public void method(Person per){
}
}
测试类:
public static void main(String[] args) {
PuTong pt=new PuTong();
//pt.method(per);此处的per是抽象类,需要创建对象
//两种方式,上转型---子类对象赋值给父类对象
//Person per1=new 子类对象;此处没有新建子类,所以可以使用匿名内部类
Person per1=new Person(){
public void method() {
}
};
pt.method(per1);
}
}
4.2接口式的匿名内部类
这个匿名内部类的作用是在不创建新类的情况下创建接口的子类,实现多个接口。
当一个类中的方法参数是接口类型时,我们可以传递接口回调对象/子类对象,如果不想额外的创建一个接口的子类,这时我们使用匿名内部类也是可以的。
例:
//接口
public interface TestInterface {
//抽象方法
public abstract void method();
}
//普通类
public class PuTong{
//实例方法参数是抽象对象
public void method(TestInterface tsi){
}
}
测试类:
public class Main {
public static void main(String[] args) {
PuTong pt=new PuTong();
//pt.method(tsi);此处的tsi是接口类,需要创建对象
//两种方式,接口回调对象---子类对象赋值给父类对象
//Person per1=new 子类对象;此处没有新建子类,所以可以使用匿名内部类
TestInterface tsi1=new TestInterface(){
public void method() {
}
};
pt.method(tsi1);
}
}
4.3 匿名内部类优缺点
优点:避免创建额外的独立子类。
缺点:不易理解,不易阅读。
最后
以上就是爱听歌大山为你收集整理的10.java内部类10.java内部类的全部内容,希望文章能够帮你解决10.java内部类10.java内部类所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复