请问inner class的一点小问题?

Y17083 2007-11-09 07:10:19
问个问题:
是不是inner class的methods必须通过outer class创建的对象调用啊?inner class创建的对象可不可以调用outer class的methods?
谢谢指教。
...全文
189 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
Y17083 2007-11-16
  • 打赏
  • 举报
回复
想给分 可是不会加 也不知道也分不? 杂加啊?
cracker234 2007-11-15
  • 打赏
  • 举报
回复
留个脚印
changlang 2007-11-15
  • 打赏
  • 举报
回复
留个脚印,有空在发言,呵呵
qybao 2007-11-14
  • 打赏
  • 举报
回复
补充一下,这样可能问题2更方便理解

class Inner {
public String fieldFive;
String fieldSix;
protected String fieldSeven;
private String fieldEight;

public Inner() {
//this.fieldOne = "I-one";//这样不行
Outer.this.fieldOne="I-one";//这样是可以的,这个跟下面一句是等效的,理由就是下面的说的,Outer.this被省略而已
fieldOne = "I-one"; //问题2A 从问题前提1知道,这里的fieldOne实际上是通过Outer的当前instance实例调用的,只是这个实例被省略了,这里并不是通过Inner实例本身调用的,也就是this.fieldOne="one";是错的,因为对于Inner来说this是Inner的当前instance实例
qybao 2007-11-14
  • 打赏
  • 举报
回复
为了方便说明,把这些问题分为3个
问题1 [outer class创建的对象]...
问题2 [inner class创建的对象]...
问题3 THINKING IN JAVA中的...

可以通过下面的例子去说明

public class Outer {
public String fieldOne;
String fieldTow;
protected String fieldThree;
private String fieldFour;

public static void main(String[] args) {
Outer out = new Outer();
//out.fieldFive = "new-O-five"; //问题1-1 Outer对象本身并不能直接访问Inner的属性和方法,必须通过Inner的实例去访问,参看问题1-2
//out.methodFive();
Outer.Inner in = new Outer().new Inner();

//in.fieldOne = "new-I-one"; //问题2-1 Inner对象本身并不能直接访问Outer的属性或方法,必须通过Outer的实例去访问,参看问题2-2
//in.methodOne();
in.useOuterInstance();
}

public Outer() {
fieldOne = "O-one"; //问题前提1 要知道,这里相当于this.fieldOne,也就是通过Outer的当前instance实例this调用的,只是this可以省略
fieldTow = "O-tow";
fieldThree = "O-three";
fieldFour = "O-four";
methodOne();//问题前提2 这里相当于this.methodTow(),也就是通过Outer的当前instance实例this调用的,只是this可以省略
methodTow();
methodThree();
String s = methodFour();
System.out.println(s);

//问题1-2 Outer要访问Inner的属性或方法,就必须创建Inner对象
Inner in = new Inner();
//fieldFive = "O-five"; //问题1A 根据问题前提1,这里相当于this.fieldFive="O-five";this就是Outer的当前instance实例,显然是不行的,也就是Outer对象本身不能直接调用Inner的属性,必须通过生成Inner的instance实例去调用
in.fieldFive = "O-five";
in.fieldSix = "O-six";
in.fieldSeven = "O-seven"; //问题3前提1 Outer类能访问Inner类的不可见属性
in.fieldEight = "O-eight";
//methodFive();//问题1B 根据问题前提2,这里相当于this.methodFive();this就是Outer的当前instance实例,显然是不行的,也就是Outer对象本身不能直接调用Inner的方法,必须通过生成Inner的instance实例去调用
in.methodFive();
in.methodSix();
in.methodSeven(); //问题3前提2 Outer类能访问Inner类的不可见方法
in.methodEight();
s = in.methodEight();
System.out.println(s);
}

public void methodOne() {
System.out.println("methodOne:" + fieldOne);
}

void methodTow() {
System.out.println("methodTow:" + fieldTow);
}

protected void methodThree() {
System.out.println("methodThree:" + fieldThree);
}

private String methodFour() {
System.out.println("methodFour:" + fieldFour);
return this.getClass().getName();
}

class Inner {
public String fieldFive;
String fieldSix;
protected String fieldSeven;
private String fieldEight;

public Inner() {
//this.fieldOne = "I-one";
fieldOne = "I-one"; //问题2A 从问题前提1知道,这里的fieldOne实际上是通过Outer的当前instance实例调用的,只是这个实例被省略了,这里并不是通过Inner实例本身调用的,也就是this.fieldOne="one";是错的,因为对于Inner来说this是Inner的当前instance实例
fieldTow = "I-tow";
fieldThree = "I-three"; //问题3前提3 Inner类可以访问Outer类的不可见属性
fieldFour = "I-four";
//this.methodOne();
methodOne(); //问题2B 从问题前提2知道,这里的methodOne()实际上是通过Outer的当前instance实例调用的,只是这个实例被省略了,这里并不是通过Inner实例本身调用的,也就是this.methodOne();是错的,因为对于Inner来说this是Inner的当前instance实例
methodTow();
methodThree(); //问题3前提4 Inner类可以访问Outer类的不可见方法
String s = methodFour();
System.out.println(s);


fieldFive = "I-five"; //问题2C 根据问题前提1 这里相当于this.fieldFive="five";this就是Inner的当前instance实例,只是被省略了
fieldSix = "I-six";
fieldSeven = "I-seven";
fieldEight = "I-eight";
methodFive();//问题2D 根据问题前提2 这里相当于this.methodFive();this就是Outer的当前instance实例,只是被省略了
methodSix();
methodSeven();
s = methodEight();
System.out.println(s);
}

public void methodFive() {
System.out.println("methodFive:" + fieldFive);
}

void methodSix() {
System.out.println("methodSix:" + fieldSix);
}

protected void methodSeven() {
System.out.println("methodSeven:" + fieldSeven);
}

private String methodEight() {
System.out.println("methodEight:" + fieldEight);
return this.getClass().getName();
}

void useOuterInstance() {
//问题2-2 Inner可以创建Outer对象来访问其属性和方法
Outer out = new Outer();
out.fieldOne = "new-O-one";
out.fieldTow = "new-O-tow";
out.fieldThree = "new-O-three";
out.fieldFour = "new-O-four";
out.methodOne();
out.methodTow();
out.methodThree();
String s = out.methodFour();
System.out.println(s);
}
}
}


从问题3的前提可以看出,就像我上面说的inner class可以访问一切outer class的属性和方法
访问权限是指public,(default),protected,private 至于LS有提到static和非static的访问限制,那是另外的话题,跟问本次说明无关。
问题3可以通过下面的例子去理解,所谓enclosing class,应该是指包围着inner class的类,因为inner class可以嵌套,甚至多个inner class并列

interface Inner6 {
void methodSix();
}

public class Inner {
public static void main(String[] args) {
new Inner().new Inner2().new Inner3().methodThree();
new Inner().new Inner4().methodFour();
new Inner().methodFive();
}

void methodOne() {
System.out.println(this.getClass().getName());
}

void methodFive() {
class Inner5 {
void methodFive() {
methodOne(); //类Inner5被类Inner包围着,所以Inner5可以访问其属性和方法
//methodTow();//类Inner5没有被类Inner2包围着,所以Inner5不可以访问其属性和方法
//methodThree();//类Inner5没有被类Inner3包围着,所以Inner5不可以访问其属性和方法
//methodFour();//类Inner5没有被类Inner4包围着,所以Inner5不可以访问其属性和方法
System.out.println(this.getClass().getName());
}
}

new Inner5().methodFive();

new Inner6() {
public void methodSix() {
methodOne(); //类Inner6被类Inner包围着,所以Inner6可以访问其属性和方法
//methodTow();//类Inner6没有被类Inner2包围着,所以Inner6不可以访问其属性和方法
//methodThree();//类Inner6没有被类Inner3包围着,所以Inner6不可以访问其属性和方法
//methodFour();//类Inner6没有被类Inner4包围着,所以Inner6不可以访问其属性和方法
System.out.println(this.getClass().getName());
}
}.methodSix();
}

class Inner2 {
void methodTow() {
methodOne();//类Inner2被类Inner包围着,所以Inner2可以访问其属性和方法
//methodFour();//类Inner2没有被类Inner4包围着,所以Inner2不可以访问其属性和方法
System.out.println(this.getClass().getName());
}

class Inner3 {
void methodThree() {
methodOne();//类Inner3被类Inner包围着,所以Inner3可以访问其属性和方法
methodTow();//类Inner3被类Inner2包围着,所以Inner3可以访问其属性和方法
//methodFour();//类Inner3没有被类Inner4包围着,所以Inner3不可以访问其属性和方法
System.out.println(this.getClass().getName());
}
}
}

class Inner4 {
void methodFour() {
methodOne();//类Inner4被类Inner包围着,所以Inner4可以访问其属性和方法
//methodTow();//类Inner4没有被类Inner2包围着,所以Inner4不可以访问其属性和方法
System.out.println(this.getClass().getName());
}
}
}
Y17083 2007-11-13
  • 打赏
  • 举报
回复
谢谢 大家。
阿宝:
[outer class创建的对象]是指在outer class创建的inner class对象,而不是outer class对象本身
[inner class创建的对象]就应该是指在inner class中创建的outer class对象,而不是inner class对象本身。
你能举个具体的程序出来么? 我没试出来。
还有对THINKING IN JAVA中的 “inner class可以访问enclosing class (该是除inner class部分的outer class部分吧)的所有成员,就象 inner class自己拥有这些成员一样。换句话说, inner class天生具有对enclosing class所有成员的访问权力。”这句话该怎么理解啊?
谢谢指教。
qybao 2007-11-11
  • 打赏
  • 举报
回复
我个人认为,LZ的意思是
前半句是说,outer class可以调用inner class的方法
后半句是问,反过来inner class能不能调用outer class的方法?否则这个问题就没意义了,就像我上面说的,调用一个类的非static方法,就必须通过该类的实例对象去调用
如果非要按LS的意思去理解,那么LZ的问题
是不是inner class的methods必须通过outer class创建的对象调用啊?这句话里的[outer class创建的对象]是指在outer class创建的inner class对象,而不是outer class对象本身,因为outer class对象本身也不能直接调用inner class的方法。承接前半句,后半句
inner class创建的对象可不可以调用outer class的methods?这里的[inner class创建的对象]就应该是指在inner class中创建的outer class对象,而不是inner class对象本身,因为同样的inner class对象本身也不能直接调用outer class的方法。原因都是[调用一个类的非static方法,就必须通过该类的实例对象去调用]。那样的话,还有什么可问的?
这个没必要争论,每个人有每个人的理解,还说LZ自己出来说吧
Keynn 2007-11-11
  • 打赏
  • 举报
回复
1. 在方法中定义的内部类,如果要访问方法中定义的本地变量或方法的参数,则变量必须被声明final.
2.内部类可以声明为private或者protect或者abstract或者final(private不能在外部被访问)。
3.内部类可以声明为static的,但此时就不能再使用外部类的非static的成员变量和非static的成员方法。
4.非static的内部类中的成员不能声明为static的。只有在顶层类或者static的内部类中才可声明static成员。
5.要产生内部类对象,首先要产生外部类对象。

class Car
{
class Wheel
{}
class PlanWheel extends Car.Wheel
{
PlanWheel (Car car)
{
car.super();
}
public static void main(String []args)
{
Car car=new Car();
PlanWheel pw=new PlanWheel(car);
}
}
*:在main()中产生inner类的对象
Outer.Inner inner=Outer.new Inner();
sharpyuce 2007-11-11
  • 打赏
  • 举报
回复
是不是inner class的methods必须通过outer class创建的对象调用啊?inner class创建的对象可不可以调用outer class的methods?


他就是这样写的哦~
sharpyuce 2007-11-11
  • 打赏
  • 举报
回复
是不是inner class的methods必须通过outer class创建的对象调用啊?inner class创建的对象可不可以调用outer class的methods?


他就是这样写的哦~
JoJooo 2007-11-11
  • 打赏
  • 举报
回复
学习中
qybao 2007-11-11
  • 打赏
  • 举报
回复
如果像LS的这么说,那这个问题没意义,除了static方法,每个类的方法都必须通过该类的实例去调用
(new InnerClassTest().new inner()).m1(); //error!! //这里不能调用,是因为m1不是inner的方法
同样的
public void m1(){
System.out.println("Outer.m1()");
new InnnerClassTest().m2(); //这样也不能调用,这里是因为m2不是InnerClassTest的方法
}
这样,LZ的问题还有意义吗?抛开inner class不说,LS举的例子跟以下的有何分别?
class A() {
public void m1() {
System.out.println("m1");
}
}
class B() {
public void m2() {
new B().m1(); //这样行吗?显然不行,LS举的例子不是很没意思吗?
}
}
调用一个类的非static方法,就必须通过该类的实例对象去调用,我个人认为LZ的意思并不是这个意思



sharpyuce 2007-11-10
  • 打赏
  • 举报
回复

其他的内部类都是一样的
package alltest;

public class InnerClassTest {
int i;
public void m1(){
System.out.println("Outer.m1()");
}

public class inner{
public void m2(){
m1();
}
}

public static void main(String[] args) {
//The method m1() is undefined for the type
//InnerClassTest.inner
(new InnerClassTest().new inner()).m1(); //error!!
}

}
sharpyuce 2007-11-10
  • 打赏
  • 举报
回复

LZ 你说的是用inner class 对象能否调用outer class的属性和方法吧,各位大哥把LZ的问题看清楚哦

package alltest;

public class InnerClassTest {
int i;
public static void m1(){
System.out.println("Outer.m1()");
}

public static class inner{
public void m2(){
m1();
}
}
}
上面的是在内部类中调用外部类的方法和属性(其他内部类一样),这样是可以的;


package alltest;

public class InnerClassTest {
int i;
public static void m1(){
System.out.println("Outer.m1()");
}

public static class inner{
public void m2(){
m1();
}
}

public static void main(String[] args) {
//The method m1() is undefined for the type
//InnerClassTest.inner
(new InnerClassTest.inner()).m1(); //error!!
}

}
这才是用内部类的事例调用外部内的方法和属性,能吗,显然不行,我是没学过这种语法的存在,不要误导人家
magic256 2007-11-09
  • 打赏
  • 举报
回复
例如

public class Test {
private int cc = 0;
static class a{
void b(){cc = 1}; //Exception!!!!!!!!!!!
}
public static void main(String[] args) {


a aa = new a();
aa.b();

}
}
magic256 2007-11-09
  • 打赏
  • 举报
回复
首先回答你的第二个问题,内部类的好处就在于它可以封装自身并调用一切外部类的字段和方法!!!
再回答你第一个问题:答案是否.
普通情况下 确实要先实例化外部类对象才能调用内部类的成员 例如
public class Test {
class a{
void b(){};
}
public static void main(String[] args) {

Test t = new Test();
Test.a aa = t.new a();
aa.b();

}
}
但有种特殊的内部类叫做嵌套类,即在内部类声明前加上static,例如
public class Test {

static class a{
void b(){};
}
public static void main(String[] args) {


a aa = new a();
aa.b();

}
}
请看这里就不需要实例化外部类了,可以直接调用
但要注意,嵌套内部类不能访问外部类的非static成员
qybao 2007-11-09
  • 打赏
  • 举报
回复
可以
inner class可以访问out class的一切属性和方法
sharpyuce 2007-11-09
  • 打赏
  • 举报
回复
记得不可以调用;
自己写个代码测试下不就明白了~

62,628

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧