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

一、内部类的理解:

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();
    }
}  

你可能感兴趣的:(面向对象的成员之一——(内部类))