package learnJava;
public class NeibuLei {
private double weight;
private String prop="外部类的实例变量. ";
public NeibuLei() {}
public NeibuLei(double weight) {
this.weight=weight;
}
//定义一个非静态内部类,用private修饰,只能在外部类中调用
private class CowLeg{
private double length;
private String prop="内部类的实例变量. ";
private String inProp="inProp";
private String color;
public CowLeg() {}
public CowLeg(double length,String color) {
this.length=length;
this.color=color;
}
//非静态内部类的实例方法
public void info() {
String prop="局部变量.";
System.out.println("颜色:"+color+"高:"+length);
System.out.println("外部类体重:"+weight);
//非静态内部类可以直接访问外部类私有成员
//当非静态内部类方法访问某个变量时,
//外部类私有成员和内部类私有成员和内部类局部量名相同。
System.out.println(NeibuLei.this.prop+this.prop+prop);
}
//非静态内部类不能包含静态方法
}
public void test() {
CowLeg c1=new CowLeg(1.29,"black");
c1.info();
//非静态内部类对象里保存了一个外部类对象的引用
//非静态内部类可以访问外部类的private成员,但是外部类不能直接访问内部类private成员。
//必须显式创建非静态内部类对象来访问其实例成员
//System.out.println(inProp)//不能编译成功
System.out.println("内部类的"+new CowLeg().inProp);
}
public static void main(String[] args) {
NeibuLei cow=new NeibuLei(34.23);//只创建了外部类对象,没有创建内部类对象。
cow.test();
//new NeibuLei().new CowLeg().info();//创建了外部类并创建内部类,之后调用内部类方法
//CowLeg q=new CowLeg();
//new CowLeg();//main()方法是外部类的静态方法,
//不能在外部类的静态成员中使用非静态内部类
//必须通过实例去访问,内部类实例是寄生在外部类实例,所以用cow.new CowLeg()去生成内部类对象,并访问内部类方法
}
}
结果:
颜色:black高:1.29
外部类体重:34.23
外部类的实例变量. 内部类的实例变量. 局部变量.
内部类的inProp
package learnJava;
public class NeibuLei1 {
private int prop1=5;
private static int prop2=120;
static class StaticInnerClass{
private static int age=90;
private int pro=12;
public void accessOuterProp() {
//System.out.println(prop1);错误不能访问外部类非静态成员
System.out.println(prop2);//可以访问外部类的静态成员
}
}
public static void main(String[] args) {
System.out.println(StaticInnerClass.age);
//System.out.println(StaticInnerClass.accessOuterProp());通过类名只能访问静态成员
new StaticInnerClass().accessOuterProp();
System.out.println(prop2);因为在外部类的静态方法中可以直接调用静态成员。
//可以直接通过静态内部类的实例访问静态内部类对象的成员。
//不同于非静态内部类必须通过 创建外部类实例,在创建内部类实例,再调用内部类方法
}
}
//用static修饰的内部类属于外部类本身,而不属于外部类对象
//静态内部类可以包含静态静态成员,也可以包含非静态成员(相当于局部变量)
//静态内部类是外部类的类相关的,而不是外部类对象相关,静态内部类对象不是寄生在外部类实例中,而是寄生在外部类本身中。
//静态内部类对象只有外部类的类引用,没有外部类对象的引用。
//静态内部类时外部类的一个静态成员
//外部类依然不能直接访问静态内部类成员,但可以使用静态内部类的类名作为调用者来访问静态内部类的类成员。
结果:
90
120
120
在外部类内部使用内部类:
1.可以在外部类的普通方法中调用内部类,创建内部类实例。
2.与普通类区别:不能在外部类的静态成员中使用非静态内部类,因为静态成员不能访问非静态成员。
在外部类以外 使用非静态内部类:
要根据内部类的访问控制符确定:
1.省略访问控制符,只能在外部类处于同一个包中的其他类可以访问。
2.使用protected访问控制符,可被与外部类处于同一个包中的其他类和外部类的子类所访问。
3.使用public修饰的内部类,可以在任何地方都被访问。
外部类以外的地方定义非静态内部类和创建非静态内部类实例:
OutClass.InnerClass varName=OuterInstance.new InnerConstructor()
package learnJava;
public class NeibuLei2 {
public static void main(String[] args) {
Out.In qq=new Out().new In("j");//非静态内部类的构造器必须使用外部类对象来调用。
//Out yu=new Out();
SubClass sub=new SubClass(new Out(),"zilei");
}
}
class Out{
class In{
public In(String msg) {
System.out.println(msg);
}
}
}
class SubClass extends Out.In{
public SubClass(Out out,String msg) {
out.super(msg);//通过传入的Out对象来显式的调用In的构造器,super代表In类的构造器
}
}//非静态内部类In类的构造器必须使用外部类对象来调用,而super代表In类的构造器,而out代表外部类对象。
创建非静态内部类In类对象时,必须通过Out对象来调用new关键字。
当创建非静态内部类的子类SubClass对象时,必须使用Out对象作为调用者来调用In类的构造器。
在外部类以外的地方使用静态内部类
因为静态内部类时外部类类相关的,因此创建内部类对象时,无需创建外部类对象。
new Our.In()
package learnJava;
public class NeibuLei3 {
public static void main(String[] args) {
StaticOut.StaticIn in=new StaticOut.StaticIn();
}
}
class StaticOut{
static class StaticIn{
public StaticIn() {
System.out.println("静态内部类构造器");
}
}
}
静态内部类比使用外部类要简单多,只要把外部类当成静态内部类的包空间即可。应该优先使用静态内部类。
把一个内部类放在方法里定义,则这个内部类就是局部内部类。
对于局部成员,不管是局部变量还是局部内部类,他们的上一级程序单元是方法,而不是类。不能使用static修饰。
局部成员的作用域是所在的方法,其他程序单元不能访问另一个方法中的局部成员。所有的局部成员都不能使用访问控制修饰符。