JavaSE(一)内部类

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mxxrgxg/article/details/83023980

gitee代码地址:https://gitee.com/mixMi/JavaSE-self-study/tree/master/inner-class/src

一,何为内部类

在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。广泛意义上的内部类一般分为四种:

成员内部类

局部内部类

匿名内部类

静态内部类

二,成员内部类

成员内部类是最普通的内部类,它是外部类的一个成员。

 

内部类实例创建:通过外部类的实例去创建(推荐使用getInstance的方法去创建)

访问外部的权限:无限制访问外部类的所有属性和方法(包括private修饰的)

外部访问的权限:需要通过内部类的实例去访问

public class Outter {
    private String name = "outter";
    private static String property = "p";

    public Inner getInnerClass(){
        return new Inner();
    }

    public class Inner{
        public String name = "inner";
        public void innerSay(){
            String name = "innerMethod";
            System.out.println(name);//命名冲突时,会找最近的
            System.out.println(this.name);//this代表本内部类
            System.out.println(Outter.this.name);//命名冲突时要调用外部类成员,用Outter.this
            System.out.println(property);//可以任意访问外部类任意成员或方法
        }
    }
}
public class Test {
    public static void main(String[] args) {
        Outter out = new Outter();
        Outter.Inner inner = out.getInnerClass();//推荐使用
        //Outter.Inner inner = out.new Inner(); //或者也可用外部类实例去创建
        inner.innerSay();
    }
}
//运行结果
innerMethod
inner
outter
p

使用注意:

1,成员内部类中不能存在任何static属性和方法 

2,成员内部类的访问控制符可以用public、protected、private等

3,在外部类的外部不能直接去new一个成员内部类,必须使用外部类对象来创建,即 外部类对象.new 内部类();

4,如果外部类和成员内部类有命名相同的成员变量或方法,内部成员类默认访问自己的成员变量或方法,如果要访问外部类的成员变量或方法,需要用 外部类.class来调用

三,局部内部类

局部内部类被定义在方法或作用域内,只对由该方法或作用域可见,即只能被该方法或作用域调用。

 

内部类实例创建:只能在作用域内创建

访问外部的权限:无限制访问外部类的所有属性和方法(包括private修饰的)

外部访问的权限:只能通过该方法或作用域交互

public class Outter {
    private String name = "outter";

    public void display(){
        String name = "method"; //暂时没有找到访问此属性的方式
        class Inner{
            String name = "inner";
            public void say(){
                String name = "innerSayMethod";
                System.out.println(name);
                System.out.println(this.name);
                System.out.println(Outter.this.name);
            }
        }
        Inner inner = new Inner();
        inner.name = "changeName";
        inner.say();
    }
}
public class Test {
    public static void main(String[] args) {
        Outter outter = new Outter();
        outter.display();
    }
}
//运行结果
innerSayMethod
inner
outter

使用注意:

1,由于局部内部类只能被该方法或作用域调用,所以不能用访问控制符和static修饰局部内部类

局部内部类中的display()方法中定义的String name = "method"变量我暂时没有找到访问的方法,有知道的小伙伴请在评论里告诉我,感激不尽

四,匿名内部类

匿名内部类应该是我们平时用的最多的内部类,它是一个没有名称的类,先看下面这个监听器例子:

button2.addActionListener(  
    new ActionListener(){  
        public void actionPerformed(ActionEvent e) {  
        System.out.println("你按了按钮二");  
    }  
});

上面的添加监听事件的写法就是标准的匿名内部类,但是我们为什么要这么写呢。回忆一下我们在学习接口和抽象类时候的demo,例如,定义一个Animal的接口或抽象类,给它定义一个eat()的方法,然后实现一个猫和一条狗的eat()。我们用常规写法的话,至少需要3个类,即Animal、Dog和Cat。但我们写成匿名内部类的话,代码就会这样:

public abstract class Animal {
    abstract void eat();
}
public class Test {
    public static void main(String[] args) {
        Animal cat = new Animal() {
            @Override
            void eat() {
                System.out.println("猫吃鱼");
            }
        };
        cat.eat();

        Animal dog = new Animal() {
            @Override
            void eat() {
                System.out.println("狗吃。。。");
            }
        };
        dog.eat();
    }
}

 会发现我们只需要写一个类就够了(即 只写Animal,Dog和Cat在需要它们的时候再写),上例是抽象类的写法,接口的写法也类似。

使用注意:

1,使用匿名类时,我们必须是继承一个类或实现一个接口(上例中的dog和cat实际上就是继承了Animal类),但二者不可同时存在,同时也只能继承一个类或实现一个接口;

2,匿名内部类中不能定义构造函数;

3,匿名内部类中不能存在static修饰的成员和方法;

4,匿名内部类是局部内部类的一种,所以局部内部类的限制同样对匿名内部类生效;

5,匿名内部类不能是抽象的,它必须要实现继承的类或实现的接口的所有抽象方法

6,如果一个匿名内部类在方法中被声明,那么可以利用这个方法去传入你想要在匿名内部类中使用的参数,但是这些参数必须被final修饰,详细解释请看 JavaSE(二)内部类问题详解

五,静态内部类

被static修饰的内部类就是静态内部类,根据静态内容的加载顺序,我们可以得出以下结论:

1,静态内部类的创建不需要依靠外部类对象

2,静态内部类不能直接访问外部类的任何非static成员变量和方法(可以用 new 外部类().成员 的方式访问)

3,外部类的静态成员或在静态内部类中没有名字冲突时,静态内部类可直接调用

public class Outter {
    private String name = "outter";
    private static int age = 13;

    public static class Inner{
        String myName = "inner";
        public static void staticDisplay(){
            System.out.println(new Outter().name);
            System.out.println(age);
        }
        public void display(){
            System.out.println(myName);
        }
    }
}
public class Test {
    public static void main(String[] args) {
        Outter.Inner.staticDisplay();
        Outter.Inner inner = new Outter.Inner();
        inner.display();
    }
}
//运行结果
outter
13
inner

 

参考文章

java提高篇(八)----详解内部类

JAVA基础——内部类详解

猜你喜欢

转载自blog.csdn.net/mxxrgxg/article/details/83023980