美文网首页
面向对象的成员之一——(内部类)

面向对象的成员之一——(内部类)

作者: 简单_6ccd | 来源:发表于2020-07-10 21:02 被阅读0次

    一、内部类的理解:

    1.1 为什么要有内部类的存在?

    当一个事物的内部,还有部分需要一个完整的结构去进行描述,并且这个内部的完整的结构又为外部事物去提供服务,那么整个内部的完整结构最好是使用内部类。

    内部类就是一个类的定义位于另一个类的内部,那么位于内部的类就叫做内部类,包容内部类的类就是外部类。内部类和外部类都是相对的,内部类里面可以还有内部类,只要满足需求既可以定义。

    内部类英文名称为Inner Class,一般用在定义它的类或者语句块当中,在外部引用它的时候必须要给出完整的名称,因此Inner Class的名字不能与包含它的外部类类名相同。

    1.2 内部类的分类

    分为:
    1.成员内部类(static 成员内部类和非static成员内部类)
    2.局部内部类(不谈修饰符)【声明在方法内、代码块内等的内部类】、匿名对象

    1.3 内部类的使用

    1.3.1 关于成员内部类的使用 作为外部类的一个成员

    1.相对于外部类,内部类可以用四种不同的权限修饰符,而外部类一般都是用public或者缺省
    2.可以在内部类中调用外部类的成员
    3.可以用static进行修饰,但是此时就不能再使用外层类的非static的成员变量
    4.编译之后生成OuterClass$InnerClass.class字节码文件

    1.3.2 关于局部内部类的使用

    1.局部内部类可以在其类中声明属性、方法、构造器、内部类、代码块【也就是包括面向对象的基本成员】
    2.局部内部类可以声明为abstract类,因此可以被其他的内部类继承
    3.可以声明为final,表示不能被其他类继承
    4.局部内部类编译之后也会生成OuterClass$InnerClass.class字节码文件

    1.3.3 注意点

    1.非static成员内部类中的成员不能声明为static,只有在外部类或者说static的成员内部类中才可以声明为static成员
    2.外部内访问内部类的时候,需要“内部类.成员”或者说“内部类对象.成员”的方式
    3.成员内部类可以直接使用外部类的所有成员,包括私有的数据
    4.当外部类的静态成员想要部分使用内部类时,可以考虑内部类声明为静态的

    如何创建成员内部类的对象、如何在成员内部类中调用外部类的属性、方法
    外部类的使用
    代码示例

       public class InnerClassTest {
        public static void main(String[] args) {
            //创建静态的成员内部类
            Person.Bird bird=new Person.Bird ();
            //创建非静态的成员内部类
            // Person.Dog dog = new Person.Dog ();
            //这样会出错,因为非静态的成员内部类必须要创建对象,进行类的的实例化
            Person p=new Person ();
            Person.Dog dog=p.new Dog ();
            //如果写成 Person.Dog dog=new p.Dog ();这样就会报错,语法出现问题
    
            dog.info ();
            dog.show ("旺财");
    
        }
    
    }
    
    class Person {
        String name="赵大花";
        int age=1;
    
        public void eat() {
            System.out.println ("人吃饭~~");
        }
    
        //静态的成员内部类
        static class Bird {
    
        }
    
        //非静态的成员内部类
        class Dog {
            String name="旺财";
    
            public void info() {
                //直接调用外部类的属性和方法
                System.out.println (age);
                //Person.Dog.eat();不能这么写,非静态的需要实例化
                Person.this.eat ();
    
            }
    
            public void show(String name) {
                System.out.println (name);
                System.out.println (this.name);
       因为非静态类的属性必须通过创建对象去调用属性,只有静态的不需要
                System.out.println (Person.this.name);
            }
        }
    }
    

    熟悉局部内部类的基本使用
    内部类的使用
    代码示例

    public class InnerClassTest1 {
    
        此种方式使用局部内部类,不常见
        public void method() {
            声明一个局部内部类
            class A {
    
            }
        }
    
        常见如下的操作
        public Comparable getComparable() {
    
         方式一:内部声明一个接口的实现类
            class MyComparable implements Comparable {
                @Override
                public int compareTo(Object o) {
                    return 0;
                }
            }
            return new MyComparable ();
            方式二:创建了接口的匿名实现类的匿名对象
            return new Comparable () {
                @Override
                public int compareTo(Object o) {
                    return 0;
                }
            };
    /new Comparable () {
            @Override
            public int compareTo(Object o) {
                return 0; }}它表示了接口的匿名实现类的匿名对象,因为只使用一次,所以可以用接口的匿名实现类,然后通过重写方法就进行了对象的创建*/
        }
    }
    
    

    二、关于内部类的使用细节

    2.1 如何使用局部内部类?

    1.只能在声明他的方法或者代码块中使用,而且是先声明后使用。除此之外的任何地方都不能使用该类
    2.但是她的对象可以通过外部方法的返回值返回使用,返回值类型只能是局部内部类的父类或者说是父接口类型
    3.内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号,以及数字编号。
    4.只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方都不能使用该类。
    5.局部内部类可以使用外部类的成员,包括私有的。
    6.局部内部类可以使用外部方法的局部变量,但是必须是final的。由局部内部类和局部变量的声明周期不同所致。
    7.局部内部类和局部变量地位类似,不能使用public,protected,缺省,private
    8.局部内部类不能使用static修饰,因此也不能包含静态成员

    2.2 匿名内部类

    1.匿名内部类不能定义任何静态成员、方法和类,只能创建匿名内部类的一个实例。一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
    2.格式:

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

    3.匿名内部类的特点
    ①匿名内部类必须继承父类或实现接口
    ②匿名内部类只能有一个对象
    ③匿名内部类对象只能使用多态形式引用

    代码示例

    interface  A{
        public  abstract void fun1();
    }
    public class Outer{
        public static void main(String[] args) {
            new Outer().callInner(new A(){
                   //接口是不能new但此处比较特殊是子类对象实现接口,只不过没有为对象取名
                public void fun1() {
                    System.out.println(“implement for fun1");
                }
            });// 两步写成一步了
        }
        public void callInner(A a) {
            a.fun1();
        }
    }  
    
    

    相关文章

      网友评论

          本文标题:面向对象的成员之一——(内部类)

          本文链接:https://www.haomeiwen.com/subject/dexvcktx.html