Java-内部类
目录
1.成员内部类
类一般都可以有方法,变量。变量(方法)中因为static的有无而有了类变量(方法)和成员变量(方法),这篇暂不描述static关键字对于变量(方法)的影响。
public class Body{
private int num =10;//成员变量
public void test(){
System.out.println("成员方法") ; //成员方法
}
public static void main(String[]args){
Body body = new Body();
body.test();
}
}
那么在一个类中可以声明一个变量并且可以初始化,一个方法并且可以实现其方法内容。那么可以声明一个类并且实现类中的内容吗?答案是可以的。那就是内部类
public class Body{ //外部类
private int num =10;//成员变量
public void test(){
System.out.println("成员方法") ; //成员方法
}
public static void main(String[]args){
Body body = new Body();
body.test();
}
class Hand{ //成员内部类
}
}
一个类中定义了一个类,这个类就是内部类。就想上面的代码例子。Hand类就像是在Body类的内部,我们暂时叫它为成员内部类。Body相对于Hand是在外部,我们暂时叫它外部类。
那么定义一个成员内部类有什么权限呢。这个成员内部类可以访问外部类定义的变量和方法。像外部类中的成员方法一样,可以访问所有类中的变量和方法(忽略了权限修饰符),因为权限修饰符压根就没有对类中的成员方法进行访问限制,而类方法的仅无法访问成员变量(方法)。
那么外部类如何访问内部类的变量(方法)呢。这个就需要创建内部类实例化对象才能访问了。像定义一个成员变量一样创建一个内部类对象。Hand hand = new Hand();这样通过hand引用就可以访问内部类当中的元素了,但是这样访问就会收权限修饰符影响,如果要使用一个私有变量,则需要一个方法来导出。
public class Body{//外部类
public Hand hand = new Hand();
private static int num =10;//成员变量
public void test(){
System.out.println("成员方法"+num) ; //成员方法
}
public void test2() { //访问内部类
hand.test1();
System.out.println("内部类的成员变量:"+hand.data);
}
class Hand{//内部类
public int data;
public void test1() {//访问外部类的变量和方法
test();
System.out.println(num);
}
}
public static void main(String[]args){
Body body = new Body();
body.test2();
body.hand.test1();
}
}
那么假如内部类中的变量(方法)和外部类中的变量(方法)名字一样,如何在内部类中访问外部类相同的变量(方法)。那么只需要 外部类名.this.成员变量(方法)。就可以访问啦。
package com.java;
public class Body{//外部类
public Hand hand = new Hand();
private static int num =10;//成员变量
public void test(){
System.out.println("成员方法"+num) ; //成员方法
}
public void test2() { //访问内部类
hand.test1();
System.out.println("内部类的成员变量:"+hand.data);
}
class Hand{//内部类
public int data;
public int num=99;
public void test1() {//访问外部类的变量和方法
int num=88;
Body.this.test();
System.out.println(Body.this.num);
System.out.println(this.num);
System.out.println(num);
}
public void test() {
System.out.println(num);
}
}
public static void main(String[]args){
Body body = new Body();
body.test2();
body.hand.test();
System.out.println("======");
body.hand.test1();
}
}
运行结果为:
成员方法10
10
99
88
内部类的成员变量:0
99
======
成员方法10
10
99
88
说了这么多,那如果直接对内部类进行实例化对象呢。
有三种方法
//内部类如何实例化对象
Body body = new body();
//1.直接实例
Body.Hand hand1= new Body().new Hand();
hand1.innerMethod();
//2.借助外部类实例
Body.Hand hand2 = body.new Hand();
hand2.innerMethod();
//3.在方法中提供一个访问点
Body.Hand hand3 = body.getHand();//类似于单例模式,但是可以有多个实例
hand3.innerMethod();
只需要把Body变成所对应的外部类名,Hand变成所对应的内部类名就可以啦。
package com.java;
public class Body{//外部类
public Hand hand = new Hand();
private static int num =10;//成员变量
public Hand getHand(){
return new Hand();
}
public void test(){
System.out.println("成员方法"+num) ; //成员方法
}
public void test2() { //访问内部类
hand.test1();
System.out.println("内部类的成员变量:"+hand.data);
}
class Hand{//内部类
public int data;
public int num=99;
public void test1() {//访问外部类的变量和方法
int num=88;
Body.this.test();
System.out.println(Body.this.num);
System.out.println(this.num);
System.out.println(num);
}
public void test() {
System.out.println(num);
}
public void innerMethod() {
System.out.println("我是内部类中的方法");
}
}
public static void main(String[]args){
Body body = new Body();
body.test2();
body.hand.test();
System.out.println("======");
body.hand.test1();
//内部类如何实例化对象
//1.直接实例
Body.Hand hand1= new Body().new Hand();
hand1.innerMethod();
//2.借助外部类实例
Body.Hand hand2 = body.new Hand();
hand2.innerMethod();
//3.在方法中提供一个访问点
Body.Hand hand3 = body.getHand();//类似于单例模式,但是可以有多个实例
hand3.innerMethod();
}
}
另外,成员内部类中不可以声明类变量和类方法。 但是可以声明常量。
Body生成的字节码文件有两个,一个是Body.class 和Body$Hand.class
2.匿名内部类
对于接口,我们要用到这个接口的话,就需要重新定义一个类implements这个接口,并且要重写接口中的所有抽象方法。假如我们只需要使用一次这个接口的方法,我们就可以使用匿名类
创建一个接口
public interface myInterface {
//public static final int a = 0;
void method();
void method1();
}
我们来重写这个方法并且调用其中一个方法。
public class innerClass {
public static void main(String[]args) {
//第一种
myInterface interface1 = new myInterface() {
@Override
public void method() {
// TODO Auto-generated method stub
System.out.println("我笑了");
}
@Override
public void method1() {
// TODO Auto-generated method stub
}
};
interface1.method();
//第二种
new myInterface() {
@Override
public void method1() {
// TODO Auto-generated method stub
}
@Override
public void method() {
// TODO Auto-generated method stub
System.out.println("啊啊啊");
}
}.method();
}
}
输出结果:
3.静态内部类
在成员内部类的声明被static修饰,就变成了静态内部类,当然也只有内部类才能被static修饰,其他类都不行。就像类方法一样,不能访问实例变量(方法)。静态内部类也不能访问外部类中的成员变量(方法)了。
另外实例化内部类就有一点点不同了,像上述成员内部类的例子中,静态内部类的话就要这样实例化: Body.Hand hand = new Body.Hand();
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。