Java(20)内部类

内部类

一个定义在另一个类里面的类称为内部类。内部类可以分为四种形式:成员内部类,

成员内部类

内部调用外部的属性和方法

成员内部类可以无条件访问外部类的所有成员属性和方法。

其他类(例子中的RunC类)访问一个内部类的形式有三种:

  1. Outter.Inner outin=new Outter().new Inner();

  2. Outter out=new Outter();
    Outter.Inner in=out.new Inner();

  3. public Inner getInnerInstance(){return Inner};

    Outter out=new Outter();

    Outter.Inner in=out.getInnerInstance();

public class Outter {
    private String name = "Krystal";
    private int age = 20;
    private Inner innerInit=null;

    public void outterFun(){
        System.out.println("外部类的方法");
    }
    
    public Inner getInnerInstance(){
        if(innerInit==null){
            innerInit=new Inner();
            return innerInit;
        }else{
            return innerInit;
        }
    }
    class Inner {
        void fun() {
            //内部类无条件访问外部类的所有成员属性和方法,不需要声明
            outterFun();
            System.out.println(name);
            System.out.println(age);
        }
    }
}

class RunC {
    public static void main(String[] args) {
        //第一种方式:
        Outter.Inner outin=new Outter().new Inner();
        outin.fun();
//        //第二种方式:
//        Outter out=new Outter();
//        Outter.Inner in=out.new Inner();
//        in.fun();
//        //第三种方式:
//        Outter out=new Outter();
//        Outter.Inner in=out.getInnerInstance();
//        in.fun();
    }
}

/*运行结果为:
外部类的方法
Krystal
20
*/
外部调用内部的属性和方法

成员内部类可以无条件访问外部类的所有成员属性和方法,但是外部想访问内部就没那么简单了。首先要创建一个成员内部类的对象,然后通过该对象访问。

其他类(例子中的RunC类)访问一个外部类的方式跟平时一样,正常调用即可。

public class Outter {
    Inner in=new Inner();
    void outterFun(){
        System.out.println(in.salary);
        in.innerFun();
    }
    class Inner {
        public void innerFun() {
            System.out.println("内部类的方法");
        }
        private long salary=25000;
    }
}

class RunC {
    public static void main(String[] args) {
        Outter ot=new Outter();
        ot.outterFun();
    }
}
/*运行结果为:
25000
内部类的方法
*/

局部内部类

局部内部类是定义在一个方法内或者一个作用域内的类。局部内部类的访问权限仅限于方法内或者作用域内。

class Outter{
    private String name="krystal";
    public void outterFun(){
        class Woman{
            int age=18;
        }
        //方法内定义的局部内部类的成员属性和方法只能在该方法内使用
        System.out.println(new Woman().age);
    }

    //Woman w=new Woman();--->编译报错
}
class RunC{
    public static void main(String[] args) {
        Outter out=new Outter();
        out.outterFun();
    }
}
//运行结果: 18

匿名内部类(常用)

首先来了解以下什么叫做匿名类,匿名类就是没有名称的类,匿名类的名称由java的编译器给出,格式形如:外部类名称+$匿名类顺序。

既然匿名类没有名称,没有名称就不能被其它地方引用,不能被实例化,所以匿名类只能用一次,也不能由构造器。

匿名类可以继承父类的方法,也可以重写父类的方法。

匿名类必须继承一个父类或者实现一个接口。创建语法格式如下:

new 父类构造器(实参列表) | 实现接口()
{
      //匿名内部类的类体部分
}

匿名类可以访问外部类的成员属性和方法,匿名类的类体不可以声明static变量或static方法。

了解了匿名类之后,那么放在一个类内部的匿名类就是匿名内部类。

案例1:通过继承实体类创建匿名内部类

class Outter{
    public String name="krystal";
    void show(){
        System.out.println("我叫"+name);
    }
}
class RunC{
    public static void main(String[] args) {
        //通过实体类创建匿名内部类,相当于创建一个该类的子对象
        Outter out=new Outter(){
            //匿名内部类可以重写父类的方法:
            @Override
            void show() {
                System.out.println("我叫Jimmy");
            }
        };
        out.show();
        //匿名内部类可以继承父类的属性和方法:
        System.out.println(out.name); 
        //查看编译器分配给匿名内部类的名称
        System.out.println(out.getClass());
    }
}
/*运行结果为:
我叫Jimmy
krystal
class RunC$1
*/

案例2:通过实现接口创建匿名内部类

interface OutF{
    public double getPrice();
    public String getName();

}
class RunC{
    public static void main(String[] args) {
        OutF oF=new OutF() {
            @Override
            public double getPrice() {
                return 153.45;
            }

            @Override
            public String getName() {
                return "shit";
            }
        };
        System.out.println(oF.getName());
        System.out.println(oF.getPrice());
        System.out.println(oF.getClass());
    }
}
/*运行结果为:
shit
153.45
class RunC$1
*/

静态内部类

静态内部类是定义在一个类内且加了static关键字的类。静态内部类不能访问外部类的非静态成员变量和方法,因为外部类的非static成员必须通过具体的对象来访问,如果静态内部类可以访问非static的外部类成员,就破坏了这一原则。

class staClass{
    private String cls_id;
    static class Innersta{
        void fun(){
            // System.out.println(cls_id); 
            // 报错Non-static field 'cls_id' cannot be referenced from a static context
        }
    }
}
posted @ 2020-08-29 09:15  Whatever_It_Takes  阅读(188)  评论(0编辑  收藏  举报