内部类-------类和对象
前置知识:
(360条消息) 记final与静态内部类的疑惑_山鬼谣me的博客-CSDN博客
1)在普通方法里面可以访问静态成员变量,因为在普通的成员方法里面第一个参数里面就包含了this,this也是可以访问静态成员变量
class Father{public static int a=10;public void run(){System.out.println(a);} }2)在静态方法里面不可以进行访问普通的成员变量: 没有创建对象实例,所以还没有非静态的成员,所以不能调用,况且静态方法里面没有this,那么你说该如何访问普通成员变量呢?
class Father{public int a=10;public static void run(){System.out.println(a);//这个语句块会爆红} }因为就是说一个指向空的引用也可以访问一个静态成员方法,静态成员方法的调用是不会依据对象的
内部类:本地内部类,实例内部类,静态内部类,匿名内部类
以后再说类的时候,一定要说明白到底是哪一个内部类,不能光说一个内部类,因为内部类之间是有很大的差异性的
1.本地内部类:
定义在方法或者是代码块里面的类,只能在当前方法或者是代码块中使用
不能被public private所修饰
public static void func(){class Student{int num=0;String name;}}
2.实例内部类:
定义在类内部的类是一个普通的类,他是和成员变量和方法是同一级别的,可以把它当成外部类的一个普通实例成员变量
1)在实例内部类里面是不可以定义静态成员变量和静态成员方法的
2)如果想要非得定义静态变量,那么它只能是由final修饰的静态常量,只能定义静态常量
3)实例内部类里面也是可以有构造方法的
class Father{class Child{public Child(){System.out.println("我是内部类");}//public static int a=10;这个代码会出现报错public static final int b=90; //这样写就是说要想在实例内部类里面定义一个静态成员变量必须用final来进行修饰} }为什么不可以在实例内部类里面定义一个静态成员变量呢?
1)因为静态成员变量是属于类的,而不是属于方法的(我们在这里可以把实例内部类看成是外部类的一个成员方法或者是成员字段);
2)如果非要进行定义,只能定义一个由final修饰的静态常量,常量在编译的时候就已经确定值了,一旦初始化就不能进行修改了
3)内部类相当于是跟普通的成员方法,成员变量一样都属于是普通的成员,在面是不可以进行定义静态成员变量的,因为实例内部类是依靠外部类的引用来进行调用的,但是static是属于类的,只有拥有外部类的引用,才能访问内部类,只有能访问到内部类,才可以访问内部类里面的成员变量;
4)如何获取实例化内部类的对象呢?它是如何进行实例化的呢?
4.1)我们只能通过外部类的对象来进行调用
4.2)先进行实例化外部类,创建外部类的引用;
外部类名.内部类名 自定义内部类名=外部类的引用.new 内部类();
外部类名.内部类名 自定义内部类引用=new 外部类类名().new 内部类类名();
5)这个内部类也是可以实现接口和继承,封装,多态的,内部类也是可以被其他类所继承
6)内部类的字节码文件类型是:外部类$内部类.class文件
7)在内部类所实现的一个方法里面,是可以进行访问到外部类的一些成员变量,例如打印外部类的一些属性字段,但是如果外部类和内部类有定义过相同的成员变量,相同的成员属性,那么在内部类所打印的字段中,打印出来的字段就是内部类里面的成员字段,就近原则
(外部类 int a=90,内部类 int a=100)---->打印100
package Demo; class OutClass{public int a=10;public int b=20;class InnerClass{public int a=100;public void func1(){System.out.println("我是内部类的func1方法");System.out.println(a);//打印100System.out.println(b);//打印20func2();}}public void func2(){System.out.println("我是外部类的func2方法");} } public class HelloWorld {public static void main(String[] args) {OutClass outClass=new OutClass();outClass.func2();OutClass.InnerClass innerClass=outClass.new InnerClass();innerClass.func1();} }打印结果: 我是外部类的func2方法 我是内部类的func1方法 100 20 我是外部类的func2方法8)如何在实例内部类中进行访问外部类和实例内部类同名的成员字段或者属性呢?
8.1)在我们的内部类中通过->外部类名.this.内部类和外部类相同的字段名来进行访问内部类和外部类同名的字段或者属性,外部类名.this.外部类字段/内部类和外部类同名属性,这样就可以在实例内部类当中获取到外部类的this
8.2)在实例内部类中如果包含了与外部类同名的成员变量,那么如何在实例内部类中进行访问呢,还可以创建外部类的对象来进行访问
package com.example.demo;public class Solution{public int data=100;class Node{public int data=20;public void run(){System.out.println(this.data) //打印的是20,因为this是代表当前实例内部类的引用System.out.println(Solution.this.data); //打印的是100,所以说还是要先进行获取到外部类的引用,在去访问内部类和外部类相同的成员字段或者方法Solution solution=new Solution();System.out.println(solution.data); //这个时候打印的还是100,这是我们是直接在内部类的方法里面直接创建外部类的实例 //然后再通过外部类的引用去访问内部类和外部类相同的成员字段或者属性}}public static void main(String[] args) {Solution solution=new Solution();Solution.Node child=solution.new Node();child.run();} }在我们的实例内部类里面一共包含了两个this
1)一个是外部类.this,在内部类里面我们可以直接在内部类的方法里面通过外部类类名.this来获取到外部类的this
2)一个是内部类自己的this,表示内部类的引用
10)如下:一个类继承于内部类的写法
class Father{class Child{public Child(){System.out.println("我是内部类");}//public static int a=10;这个代码会出现报错public static final int b=90;//这样写就是说要想在实例内部类里面定义一个静态成员变量必须用final来进行修饰public void run(){System.out.println("我是内部类的run方法");}} } class Child1 extends Father.Child{//外部类名.内部类名public Child1(Father father) //在要继承内部类的类里面写一个构造方法,里面传过来外部类的引用,继承于外部类的类,并且先要帮助外部类进行构造{father.super();}}
class OuterClass{public int data1=1;private int data2=2;public static int data3=3;class InnerClass{//把这个内部类当成一个外部类的一个普通的实例的成员public int a=10;private int data4=20;// public static int d=19;//这个变量是不能够定义的
因为data6不属于对象,是属于类的属性,也就是属于Innerclass
但是类Innerclass却属于OuterClass
我们吧InnerClass看成OuterClass的一个实例成员变量
将来Innerclass和func是依赖外部类对象的引用才能调用的public static final int data6=100;public Inner(){System.out.println("我是不带有参数的内部类的构造方法");}public void test(){System.out.println("我是实例内部类的中的test方法");}}public void func1(){
System.out.println("我是OuterClass的func1方法");}
}
class test{public static void main(String[] args) {OuterClass outerClass=new OuterClass();outerClass.func();OuterClass.Inner inner=outerClass.new Inner();inner.test();}
}
总结:关于实例内部类的注意事项:
1)外部类的任何成员都是可以在实例内部类的方法中进行使用
2)实例内部类所处的位置和外部类成员位置相同,因此也受public,private等关键字的影响,假设说如果内部类被private所修饰,那么这个内部类只能在外部类里面被实例化
class Father{private class Child{Child child=new Child();}Child child1=new Child(); }3)在实例内部类方法中访问同名的成员的时候,优先访问自己的,如果说要进行访问外部类同名的成员,我们可以通过外部类名.this来进行访问或者是通过外部类实例化之后的对象的引用来进行访问
4)实例内部类中的所有非静态方法中包含了一个指向外部类对象的引用
5)我们在外部类当中是不可以进行访问实例内部类的成员,如果说你想要进行访问必须要先创建实例内部类的对象
6)实例内部类中不可以定义静态成员方法,但是实例内部类是可以进行访问外部类的所有成员
3)静态内部类:相当于是一个静态方法类似的地位
被static修饰的内部类,不需要外部类对象来进行调用
1)我们可以把静态内部类看作是外部类的一个静态成员,他的实例化只通过外部类的类名来进行操作即可
2)静态内部类里面是可以静态成定义一些静态方法,静态字段,普通字段,普通方法
3)获取到静态内部类的实例:实例化静态内部类对象
外部类名.内部类名 自定义内部类名字=new 外部类名.静态内部类名();
4)我们在静态内部类内部是无法进行访问外部类的非静态成员变量,因为外部类的非静态成员,需要通过外部类对象的引用才能进行访问
那么我们如何在内部类里面进行访问外部类的普通成员变量呢?
那就是不可以的
我们要是想在静态内部类里面访问这些外部类的普通成员变量,就要依赖于外部类的对象的引用,再通过.的方式来进行访问就行了
class OuterClass{public int data1=100;public int data2=99;public int data3=88;public static int data4=11;static class InnerClass{public InnerClass(){this.out=new OuterClass();}OuterClass out=new OuterClass();public int data4=4;public int data5=5;public int data6=8;public static int data7=90;public static void func1(){
//System.out.println(data4);这里面会出现爆红,是不可以进行访问的内部类的非静态成员字段的
//System.out.println(data1);
//System.out.println(data2);
//System.out.println(data3);在我们的内部类里面,无法访问data1,data2,data3,
//因为data1和data2的调用,是依赖于外部类的引用来进行调用的
//而我们的静态内部类进行调用的时候,是不依据于外部类的引用来进行调用的System.out.println("我是静态内部类中的func1()方法,我是内部类中的一个静态方法");}public void func2(){ System.out.println(out.data1);System.out.println("我是静态内部类中的一个普通方法");}}
}
class test{public static void main(String[] args) {OuterClass.InnerClass innerClass=new OuterClass.InnerClass();innerClass.func1();}
}
打印结果:
我是静态内部类的func1方法
10
20
30
package Demo;
class OuterClass{public int data1=10;public int data2=20;public int data3=30;static class InnerClass{public int data4=90;private int data5=80;public void func1(){System.out.println("我是静态内部类的func1方法");OuterClass outerClass=new OuterClass();System.out.println(outerClass.data1);System.out.println(outerClass.data2);System.out.println(outerClass.data3); }}
}public class HelloWorld {OuterClass.InnerClass innerClass = new OuterClass.InnerClass();}
但是还是要注意下我们虽然在内部类里面创建了外部类的实例,但是我们通过外部类的实例在内部类里面是访问不到外部类的private字段和属性的,你要想访问只能提供getter和setter方法
下面通过内部类构造方法来进行传递一个外部类的引用也是可以的:
package Demo;import javassist.runtime.Inner;class OuterClass{public int data1=10;public int data2=20;public int data3=30;static class InnerClass{OuterClass outerClass;public InnerClass(OuterClass outerClass){this.outerClass=outerClass;}public int data4=90;private int data5=80;public void func1(){System.out.println("我是静态内部类的func1方法");System.out.println(outerClass.data1);System.out.println(outerClass.data2);System.out.println(outerClass.data3); }}
}public class HelloWorld {public static void main(String[] args) {OuterClass o=new OuterClass();OuterClass.InnerClass innerClass = new OuterClass.InnerClass(o);innerClass.func1();}}
这么写也是可以的
4.匿名内部类
class Text{public void func1(){System.out.println("我是父类的构造方法");} } public class test extends Text{public static void main(String[] args) {Text t1= new Text(){@Overridepublic void func1() {System.out.println("我是匿名内部类重写的方法");}};t1.func1();} }package Demo; class Test{public void run(){System.out.println("我是JAVA大佬");} } public class HelloWorld{public static void main(String[] args) {new Test(){public void run(){System.out.println("我是C++大佬");}}.run();} }
总结:
为什么实例内部类里面可以访问外部类所有的成员变量?
我们把实例内部类当成是一个普通的成员方法,在普通的成员方法里面是可以访问静态成员和非静态成员的
为什么实例内部类里面不可以定义一个静态成员变量?
从这个角度来想,实例内部类的使用是依靠外部类的引用来进行调用的,但是内部类的静态成员变量是不依赖于对象的
为什么静态内部类里面不可以访问外部类的非静态成员变量?
把静态内部类当作是和静态方法是一个级别的,在静态方法里面本来是不可以进行访问非静态成员变量的
为什么静态内部类里面可以定义静态成员变量和普通的成员变量?
因为静态内部类的调用不依赖于外部类的实例,静态内部类他是不依赖于对象的
内部类的字节码:外部类名$内部类.class
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
