外部类能访问内部类的成员

深入理解Java内部类
外部类能访问内部类的成员,内部类的一些知识 
成员内部类: 
相当于类的非静态成员,可以用权限修饰符来修饰,包括private、protected、public. 
1、定义成员内部类 
class Outter { 
//非静态内部类 
class Inner { 
//内部类成员 
int i = 12; 
} 
//外部类的普通成员 
int j = 0; 
} 


2、外部类之内创建成员内部类对象 
语法和普通的创建对象相同,用new操作符调用相应的构造方法即可。注意的是,非静态内部类属于外部类的非静态成员,不能在静态上下文使用。 
例子: 
class Outter { 
//非静态内部类 
class Inner { 
//内部类成员 
int i = 12; 
public void innerTest() { 
System.out.println(“Inner Class Method”); 
} 
} 
//外部类的普通成员 
int j = 0; 
public void test() { 
Inner inner = new Inner(); 
inner.innerTest(); 
} 
} 


3、外部类之外创建成员内部类对象 
既然是外部类的非静态成员,就必须在外部类对象存在的情况下使用。 
基本语法是 
<外部类类名>.<内部类类名> 引用变量名称 = <外部类对象的引用>.new <内部类构造器>; 
<外部类类名>.<内部类类名> 引用变量名称 = new <外部类构造器>.new <内部类构造器>; 
(1)、创建内部类对象时对象引用必须是<外部类类名>.<内部类类名> 
(2)、调用内部类的构造方法不能直接用new 而是要用<外部类对象的引用>.new调用 
例子: 
class Outter { 
//非静态内部类 
class Inner { 
//内部类成员 
int i = 12; 
public void innerTest() { 
System.out.println(“Inner Class Method”); 
} 
} 
//外部类的普通成员 
int j = 0; 
} 
class MainTest { 
public static void main(String[] args) { 
Outter outter = new Outter(); 
Outter.Inner inner = outter.new Inner(); 
inner.innerTest(); 
} 
} 


在外部类之外访问内部类时需要注意权限修饰符的限制,这点和类成员一样。 
3、内部类编译后生成的.class文件名称格式是<外部类类名>$<内部类类名>。
4、内部类与外部类之间的成员互相访问 
内部类可以访问外部类的任何成员,包括private成员。 
外部类访问内部类的成员需要创建内部类的对象,之后可以访问内部类的任何成员,包括private成员,需要注意的是成员内部类不可以有静态成员。 
当外部类的成员和内部类的成员重名时单单用this是区分不了的。在内部类中访问外部类的成员时可以用如下语法区分 
<外部类类名>.this.<外部类中需要被访问的成员名>;
局部内部类 
内部类定义在方法中成为局部内部类,只在局部有效。该类只为所在的方法块服务。 
局部内部类和成员内部类一样可以访问外围类的所有成员,但是不可以访问同在一个局部块的普通局部变量。如果要访问,此局部变量要被声明称final的。 
代码块结束后普通的局部变量会消亡,而创建的局部内部类对象并不会随着语句块的结束而消亡。final的局部变量的存储方式和普通的局部变量不同,其不会因为语句块的结束而消失,还会长期存在,因此可以被局部内部类访问。
例子: 
public class InnerClassTest1 { 
public static void main(String[] args) { 
Outter outter = new Outter(); 
ForInner forInner = outter.getInner(); 
forInner.sayHello();
} 
} 
class Outter { 
ForInner forInner; 
public ForInner getInner() { 
class Inner implements ForInner { 
public void sayHello() { 
System.out.println("你好,我是局部内部类对象,我还存在!"); 
} 
} 
forInner = new Inner(); 
return forInner;
} 
} 
interface ForInner { 
void sayHello(); 
} 


由于局部内部类只在局部有效,所以不能在外面用局部内部类的引用指向局部内部类的对象,只能用局部内部类实现接口并创建局部内部类对象,在外面用接口引用指向局部内部类对象。 
静态方法中的局部内部类只能访问外围类的静态成员,访问不了非静态成员。 
局部内部类生成的.class文件名称是<外部类类名>$<n><内部类类名>其中n是该局部的第几个内部类
静态内部类 
静态内部类的定义 
class Outter { 
static class Inner { 
/****/ 


由于静态内部类是外部类的静态成员,所以静态内部类只能访问外部类的静态成员。并且创建静态内部类的对象不依赖外部类的对象。在外部类之外创建静态内部类对象的语法如下 
<外部类类名>.<内部类类名> 引用变量名 = new <外部类类名>.<内部类构造器>; 
例子: 
class Outter { 
static class Inner { 
public void sayHello() { 
System.out.println(“成功创建静态内部类对象!”); 
} 
} 
public void getInner() { 
//在外部类中创建静态内部类的对象 
Inner ii = new Inner(); 
ii.sayHello(); 
} 
} 
public class MainTest { 
public static void main(String[] args) { 
//在外部类外创建静态内部类的对象 
Outter.Inner i = new Outter.Inner(); 
i.sayHello(); 
//在外部类中使用静态内部类的对象 
new Outter().getInner(); 
} 
} 


静态内部类实际上已经脱离了外部类的控制,创建对象时也不再需要外部类对象的存在,实质上只是一个放置在别的类中的普通类而已。
匿名内部类 
基于继承的匿名内部类,语法如下: 
new <匿名内部类要继承父类的对应构造器> { 
//匿名内部类类体 
}; 
基于实现接口的匿名内部类,语法如下: 
new <接口名> { 
//匿名内部类类体,实现接口中的所有方法 

匿名内部类中使用外面的变量要被声明成final的。 
匿名内部类对象初始化的代码可以写在其非静态块中 
匿名内部类生成的.class文件是<外部类类名>$<n>.class n是该类的第几个匿名内部类。
各种内部类可用的修饰符 
成员内部类 
final、abstract、public、private、protected、static 
静态内部类 
final、abstract、public、private、protected 
局部内部类 
final、abstract 
匿名内部类 
不能对匿名内部类使用修饰符
内部接口 
定义在类中的内部接口无论是否被static修饰都是静态成员。 
内部接口声明成private的意味着只能被外部类中的某个内部类来实现。 
内部接口不能扮演局部的角色,否则编译报错。因为接口的设计初衷是对外公布,让很多类实现,而局部的角色违背了接口的设计初衷。 
接口中的内部接口属于接口的成员,具有接口成员的所有属性,不能用private进行修饰。 
外部接口外实现内部接口的语法如下: 
class <类名> implements <外部接口名>.<内部接口名> { 
//类体 
}
 
通过这个看也好 
http://loving.javaeye.com/blog/190775 
lovewhzlq (CTO) 2009-10-12
new PrivateClassTest().new A().aa
分三步看。 
第一个对象PrivateClassTest()。 
通过该对象引用可以访问访问权限为package private的内部类A(),并生成一个新的对象。 
在这个对象引用中,aa是其内部成员,当然可以访问。
<think> 我们正在讨论C++中嵌套类(内部类访问外部类成员的问题。根据引用[1],嵌套类默认不是外部类的友元,因此不能直接访问外部类的非静态私有成员。我们需要遵循以下规则: 1. 静态成员:嵌套类可以直接访问外部类的所有静态成员(包括private)。 2. 非静态成员:必须通过外部类实例访问其公有或保护成员;若要访问私有成员,则需要在外部类中声明嵌套类为友元。 此外,引用[2]提到了一种封装多个成员变量的方法,但这里我们更关注如何让嵌套类访问外部类成员。 因此,实现嵌套类访问外部类成员变量的方法主要有两种: 方法一:通过外部类对象访问(仅限公有和保护成员) 方法二:在外部类中将嵌套类声明为友元,这样嵌套类就可以直接访问外部类的私有成员。 下面我们用代码示例来说明。 假设我们有一个外部类Outer和一个嵌套类Inner。 方法一:通过外部类对象访问(适合公有或保护成员) 在嵌套类中,如果我们需要访问外部类的非静态成员,必须有一个外部类的对象。通常,我们可以在嵌套类的成员函数中传递一个外部类的引用或指针。 方法二:使用友元声明(可以访问私有成员) 在外部类中声明嵌套类为友元,这样嵌套类就可以访问外部类的所有成员(包括私有成员)。 下面分别给出两个示例: 方法一示例(通过对象访问): ```cpp class Outer { public: int publicVar; protected: int protectedVar; private: int privateVar; // 嵌套类不能直接访问,除非有友元声明 public: class Inner { public: void accessOuter(Outer& outer) { outer.publicVar = 10; // 可以访问公有成员 outer.protectedVar = 20; // 可以访问保护成员 // outer.privateVar = 30; // 错误:不能访问私有成员 } }; }; ``` 方法二示例(使用友元): ```cpp class Outer { private: int privateVar; public: class Inner; // 前向声明(如果Inner的定义在Outer之后,则需要此声明) // 声明嵌套类Inner为友元 friend class Inner; class Inner { public: void accessOuter(Outer& outer) { outer.privateVar = 30; // 正确:因为Inner是Outer的友元 } }; }; ``` 注意:在方法二中,我们在外部类中声明了嵌套类为友元,这样嵌套类就可以访问外部类的私有成员。 但是,需要注意友元声明的位置。有时嵌套类的定义在外部类内部,我们可以直接在外部类内部声明友元,如上述示例。如果嵌套类定义在外部类外部,则需要在外部类中声明友元,并且嵌套类的定义需要放在外部类之后(此时可能需要前向声明)。 另外,还有一种常见场景:嵌套类作为外部类成员,并且外部类可能希望嵌套类能够访问外部类的私有成员,但又不想将整个嵌套类暴露为友元(或者嵌套类中只有部分函数需要访问)。这时可以选择只将嵌套类的特定成员函数声明为友元。但请注意,嵌套类的成员函数在外部类中声明为友元时,需要完整的限定名。 例如: ```cpp class Outer { private: int privateVar; public: class Inner { public: void accessOuter(Outer& outer); void anotherFunction(Outer& outer); // 这个函数不能访问私有成员 }; // 声明Outer::Inner::accessOuter为友元 friend void Inner::accessOuter(Outer& outer); }; // 在外部定义Inner的成员函数 void Outer::Inner::accessOuter(Outer& outer) { outer.privateVar = 30; // 可以访问 } void Outer::Inner::anotherFunction(Outer& outer) { // outer.privateVar = 40; // 错误:不能访问私有成员 } ``` 总结: - 访问静态成员:嵌套类可以直接访问外部类的静态成员(包括私有静态成员)。 - 访问非静态成员: 1. 对于公有和保护成员:通过外部类对象访问。 2. 对于私有成员:需要将嵌套类(或嵌套类的特定成员函数)声明为外部类的友元。 以上就是C++中嵌套类访问外部类成员变量的实现方法。 注意:嵌套类(内部类)和外部类之间没有特殊的访问权限,除非显式声明友元关系。 §§相关问题§§ 1. C++中嵌套类可以访问外部类的私有静态成员吗? 2. 除了友元声明,还有其他方法让嵌套类访问外部类的私有成员吗? 3. 在嵌套类中如何访问外部类的非静态成员变量? 4. 嵌套类与外部类之间的访问权限与继承有什么区别? </think> ### C++内部类访问外部类成员变量的实现方法 在C++中,内部类(嵌套类)访问外部类成员需要遵循特定规则,以下是完整的实现方法: #### 1. **直接访问静态成员** 内部类可直接访问外部类的**所有静态成员**(包括private): ```cpp class Outer { private: static int staticPrivateVar; public: class Inner { public: void accessStatic() { staticPrivateVar = 42; // 直接访问外部类私有静态成员 } }; }; ``` #### 2. **通过外部类实例访问公有/保护成员** 对于**非静态成员**,需通过外部类实例访问: ```cpp class Outer { public: int publicVar; protected: int protectedVar; private: int privateVar; // 无法直接访问 class Inner { public: void accessNonStatic(Outer& outer) { outer.publicVar = 10; // ✔ 访问公有成员 outer.protectedVar = 20; // ✔ 访问保护成员 // outer.privateVar = 30; // ❌ 错误:私有成员不可访问 } }; }; ``` #### 3. **友元声明访问私有成员** 需在外部类中声明内部类为`friend`: ```cpp class Outer { private: int privateVar; public: class Inner; // 前置声明 friend class Inner; // 关键:友元声明 class Inner { public: void accessPrivate(Outer& outer) { outer.privateVar = 30; // ✔ 直接访问私有成员 } }; }; ``` #### 4. **嵌套封装结构体** 通过结构体封装相关变量(引用[2]方法): ```cpp class Outer { private: struct DataBundle { // 封装相关变量 int var1; int var2; } data; public: class Inner { public: void modifyBundle(Outer& outer) { outer.data.var1 = 100; // 通过单一接口访问 outer.data.var2 = 200; } }; // 可选:提供受控访问接口 DataBundle& getData() { return data; } }; ``` > **关键规则总结**: > 1. 静态成员内部类可无条件访问外部类所有静态成员 > 2. 非静态公有/保护成员:需通过外部类实例访问 > 3. 非静态私有成员:必须在外部类中声明`friend class Inner;` > 4. 封装结构体:适用于逻辑关联紧密的变量组(但需注意封装性)[^2] ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值