2020年9月1日 类的成员、静态成员内部类(静态内部类)、非静态的成员内部类

  

* 类的成员:
* 1、属性:成员变量
* 2、方法:成员方法
* 3、构造器
* 4、代码块
* 5、内部类:成员内部类
*
* 其中1、2是代表这类事物的特征
* 其中3、4是初始化类和对象用的
* 其中5协助完成2的功能的实现,表现
*
* 什么情况下会用到成员内部类(方法外声明的)?
* 当描述一个事物时,发现它的内部还有一个完整的结构需要用一个类来描述;
* 并且发现这内部的结构,如果独立存在是没有意义的,必须在这个外部类中才有意义。而且这个内部结构只为这个外部类服务。
*
* 例如:Body身体,发现它内部还有完整的结构,例如:心脏
* 发现心脏单独创建对象没有意义,只有在Body对象中才有意义,而且只为Body对象服务。

 * 成员内部类分为两种:
 * 1静态成员内部类,简称静态内部类
 * 【修饰符】 class 外部类{
 *         【其他修饰符】 static class 内部类{
 *         }
 * }
 * 【修饰符】 class 外部类  【 extends 父类】 【implements 父接口们】{
 *         【其他修饰符】 static class 内部类  【 extends 父类】 【implements 父接口们】{
 *         }
 * }
 * 注意:只有成员内部类才能用static修饰,其他的外部类,局部内部类等都不可以用static修饰
 * 
 * 2非静态成员内部类
 * 【修饰符】 class 外部类{
 *         【其他修饰符】  class 内部类  {
 *         }
 * }
 * 【修饰符】 class 外部类 【 extends 父类】 【implements 父接口们】{
 *         【其他修饰符】  class 内部类  【 extends 父类】 【implements 父接口们】{
 *         }
 * }
package com.atguigu.test02;

//import com.atguigu.test02.Outer.Inner;

/*
 * 二、静态内部类
 * 
 * 1、特点
 * (1)静态内部类中,可以出现原本类中能够定义的所有的成员
 * 属性:可以有静态属性和非静态属性
 * 方法:可以有静态方法和非静态方法
 *         如果静态内部类是抽象类的话,还可以定义抽象方法
 * 构造器:有参、无参
 * 代码块:可以有静态代码块和非静态代码块
 * 内部类:允许,很少再写内部类(不讨论内部类的内部类)
 * 
 * (2)静态内部类中不能使用外部类的非静态的成员
 * (3)在外部类中,使用静态内部类,和使用其他的类一样的原则
 * 如果使用静态内部类的静态成员,直接“静态内部类名.”
 * 如果使用静态内部类的非静态成员,直接“静态内部类对象名.”
 * (4)在外部类的外面,使用静态内部类
 * 如果使用静态内部类的静态成员,直接“类名.”
 *         使用外部类名.静态内部类名.静态方法
 *         使用import 包.外部类名.静态内部类名;  在代码中使用   “静态内部类名.”
 * 如果使用静态内部类的非静态成员,“静态内部类对象名.”
 * 
 * (5)静态内部类不会随着外部类的初始化一起初始化,而是要在使用到这个静态内部类是才会初始化
 * 
 * 
 * 2、结论
 * (1)同级的来说静态的不能直接使用非静态的
 * (2)访问一个类的静态成员,用“类名.”即可,
 *    访问一个类的非静态成员,用“对象名.”即可,
 * (3)一个类需要初始化,得用到这个类
 */
public class TestStaticInner {
    public static void main(String[] args) {
/*//        Inner.test();//上面有导包语句,import 包.外部类名.静态内部类名;
        
        Outer.Inner.test();//外部类名.静态内部类名.静态方法
        
//      Inner in = new Inner();//上面有导包语句,import 包.外部类名.静态内部类名;
        Outer.Inner in = new Outer.Inner();
        in.method();*/
        
        Outer out = new Outer();
        out.outMethod();
    }
}
class Outer{
    private int i = 1;
    private static int j = 2;
    
    static{
        System.out.println("外部类的静态代码块");
    }
    
    static class Inner{
        static{
            System.out.println("静态内部类的代码块");
        }
        
        public void method(){
            System.out.println("静态内部类的非静态方法");
//            System.out.println(i);//错误
            System.out.println(j);
        }
        
        public static void test(){
            System.out.println("静态内部类的静态方法");
        }
    }
    
    public void outMethod(){
        Inner in = new Inner();
        in.method();//非静态方法,用对象名.访问
        
        Inner.test();//静态方法,用类名.访问
    }
}
package com.atguigu.test03;

/*
 * 三、非静态的成员内部类
 * 
 * 1、特点:
 * (1)在非静态内部类中,不能出现任何和static有关的声明
 * (2)在非静态内部类中,可以随意访问外部类的所有的成员,包括静态的和非静态的
 * (3)在外部类的静态成员中,不能使用非静态的成员内部类
 * (4)在外部类的外面使用
 * 第一步:先创建外部类的对象
 * 第二步:要么通过外部类的对象,去创建内部类的对象
 *                 Outer out = new Outer();
                Outer.Inner in = out.new Inner();
 *     要么通过外部类的对象,去获取内内部类的对象
 *                 Outer out = new Outer();
 *                 Outer.Inner in  = out.getInner();
 * 
 * 
 */
public class TestNonStaticInner {
    public static void main(String[] args) {
//        Outer.Inner in = new Outer.Inner();//错误的
        
        //我们要在这里使用Inner,因为此时的Inner是Outer的非静态成员,所以需要用到Outer的对象
        Outer out = new Outer();
//        Outer.Inner in = out.new Inner();
        Outer.Inner in  = out.getInner();
        in.method();
    }
}
class Outer{
    private int i = 1;
    private static int j = 2;
    
    class Inner{
        public void method(){
            System.out.println("非静态内部类的非静态方法");
            System.out.println(i);
            System.out.println(j);
        }
    }
    
    public static void outTest(){
//        Inner in = new Inner();//静态的方法不能访问非静态的成员
    }
    public void outMethod(){
        Inner in = new Inner();
        in.method();
    }
    
    public Inner getInner(){
        return new Inner();
    }
}
package com.atguigu.test04;

import com.atguigu.test04.Outer.Inner;

public class TestExer {
    public static void main(String[] args) {
        MySub my = new MySub(new Outer());
        my.test();
    }
}
class Outer{
    abstract class Inner{
        public abstract void test();
    }
}

//class MySub 去继承Inner,重写test()打印"hello",并在测试中调用

/*
 * (1)使用非静态内部类名时,可以使用
 * import 包.外部类名.内部类名;
 * (2)要调用非静态内部类的构造器,需要用到外部类的对象
 * (3)因为子类的构造器的首行一定要调用父类的构造器,默认调用父类的无参构造
 * (4)继承抽象类,要重写抽象的抽象方法
 */
class MySub extends Inner{
    MySub(Outer out){
        out.super();//需要外部类的对象,才能调用非静态内部类的构造器
    }

    @Override
    public void test() {
        System.out.println("hello");
    }
}
原文地址:https://www.cnblogs.com/douyunpeng/p/13598928.html