整理java读书笔记十五之java中的内部类
内部类是指在一个外部类的内部再定义一个类。类名不需要和文件夹相同。
*内部类可以是静态static的,也可用public,default,protected和private修饰。(而外部顶级类即类名和文件名相同的只能使用public和default)。
前言
Java从JDK1.1的时候,就开始引入内部类的概念了,那么小编也通过这篇博客来分享一下Java中有关内部类的一些特性。
什么是内部类?
在很多情况下,类被定义成一个独立的程序单元,但是有时候也会把一个类放在另一个类的内部定义,这个定义在其他类内部的类就称为内部类。
从语法上来看的话,定义内部类和定义外部类的语法大致相同,内部类除了需要定义在其他类里面之外,还存在如下两点区别。
1.内部类比外部类多使用三个修饰符:private——protected、static——外部类不可以使用这三个修饰符。
2.非静态内部类不能拥有静态成员。
除了以上两点之外,其他的地方都与普通的类相同,下面来列举一下常见的内部类操作。
非静态内部类
定义内部类也非常简单,只要把一个类放在另一个类内部定义即可,甚至都可以放置在方法的内部。
<spanstyle="font-family:ComicSansMS;font-size:18px;">packagecom.test;
publicclassCow
{
privatedoubleweight;
//外部类的两个重载的构造器
publicCow(){}
publicCow(doubleweight)
{
this.weight=weight;
}
//定义一个非静态内部类
privateclassCowLeg
{
//非静态内部类的两个实例变量
privatedoublelength;
privateStringcolor;
//非静态内部类的两个重载的构造器
publicCowLeg(){}
publicCowLeg(doublelength,Stringcolor)
{
this.length=length;
this.color=color;
}
//下面省略length、color的setter和getter方法
publicvoidsetLength(doublelength)
{
this.length=length;
}
publicdoublegetLength()
{
returnthis.length;
}
publicvoidsetColor(Stringcolor)
{
this.color=color;
}
publicStringgetColor()
{
returnthis.color;
}
//非静态内部类的实例方法
publicvoidinfo()
{
System.out.println("当前牛腿颜色是:"
+color+",高:"+length);
//直接访问外部类的private修饰的成员变量
System.out.println("本牛腿所在奶牛重:"+weight);//①
}
}
publicvoidtest()
{
CowLegcl=newCowLeg(1.12,"黑白相间");
cl.info();
}
publicstaticvoidmain(String[]args)
{
Cowcow=newCow(378.9);
cow.test();
}
}
</span>
在上述中非静态内部类的成员可以访问外部类的private成员,但反过来就不成立了。非静态内部类的成员只在非静态内部类范围内是可知的,并不能被外部类直接使用。如果外部类需要访问非静态内部类的成员,则必须显式创建非静态内部类对象来调用访问其实例成员。
<spanstyle="font-family:ComicSansMS;font-size:18px;">packagecom.test;
publicclassOuter
{
privateintoutProp=9;
classInner
{
privateintinProp=5;
publicvoidacessOuterProp()
{
//非静态内部类可以直接访问外部类的private成员变量
System.out.println("外部类的outProp值:"
+outProp);
}
}
publicvoidaccessInnerProp()
{
//外部类不能直接访问非静态内部类的实例变量,
//下面代码出现编译错误
//System.out.println("内部类的inProp值:"+inProp);
//如需访问内部类的实例变量,必须显式创建内部类对象
System.out.println("内部类的inProp值:"
+newInner().inProp);
}
publicstaticvoidmain(String[]args)
{
//执行下面代码,只创建了外部类对象,还未创建内部类对象
Outerout=newOuter();//①
out.accessInnerProp();
}
}
</span>
注意:非静态内部类中不能有静态方法、静态成员变量、静态初始化块。
静态内部类
如果使用static来修饰一个内部类,则这个内部类就属于外部类本身,而不属于外部类的某个对象,因此使用static修饰的内部类被称为类内部类,有的地方也称为静态内部类。静态内部类可以包含静态成员,也可以包含非静态成员。根据静态成员不能访问非静态成员的规则,静态内部类不能访问外部类的实例成员,只能访问外部类的类成员。
<spanstyle="font-family:ComicSansMS;font-size:18px;">packagecom.test;
publicclassStaticInnerClassTest
{
privateintprop1=5;
privatestaticintprop2=9;
staticclassStaticInnerClass
{
//静态内部类里可以包含静态成员
privatestaticintage;
publicvoidaccessOuterProp()
{
//下面代码出现错误:
//静态内部类无法访问外部类的实例变量
System.out.println(prop1);
//下面代码正常
System.out.println(prop2);
}
}
}
</span>
匿名内部类
使用匿名内部类可以创建那种只需要一次使用的类,并且创建匿名内部类时会立即创建一个该类的实例,但是也需要注意一下规则
1.匿名内部类不能是抽象类,因为系统在创建匿名内部类时,会立即创建匿名内部类的对象,因此不允许将匿名内部类定义成为抽象类
2.匿名内部类不能定义构造器,由于匿名内部类没有类名,所以无法定义构造器
<spanstyle="font-family:ComicSansMS;font-size:18px;">packagecom.test;
interfaceProduct
{
publicdoublegetPrice();
publicStringgetName();
}
publicclassAnonymousTest
{
publicvoidtest(Productp)
{
System.out.println("购买了一个"+p.getName()
+",花掉了"+p.getPrice());
}
publicstaticvoidmain(String[]args)
{
AnonymousTestta=newAnonymousTest();
//调用test()方法时,需要传入一个Product参数,
//此处传入其匿名实现类的实例
ta.test(newProduct()
{
publicdoublegetPrice()
{
return567.8;
}
publicStringgetName()
{
return"AGP显卡";
}
});
}
}
</span>
下面给大家总结以下内部类的共性编辑
(1)、内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号。
(2)、内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否是private的。
(3)、内部类声明成静态的,就不能随便的访问外部类的成员变量了,此时内部类只能访问外部类的静态成员变量。