java 面向对象(二十五):内部类:类的第五个成员

内部类:类的第五个成员

1.定义:

Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类.
2.内部类的分类:
成员内部类(静态、非静态 ) vs 局部内部类(方法内、代码块内、构造器内)
3.成员内部类的理解:
一方面,作为外部类的成员:
* >调用外部类的结构
* >可以被static修饰
* >可以被4种不同的权限修饰
*
另一方面,作为一个类:
* > 类内可以定义属性、方法、构造器等
* > 可以被final修饰,表示此类不能被继承。言外之意,不使用final,就可以被继承
* > 可以被abstract修饰
4.成员内部类:
4.1如何创建成员内部类的对象?(静态的,非静态的)
//创建静态的Dog内部类的实例(静态的成员内部类):
Person.Dog dog = new Person.Dog();

//创建非静态的Bird内部类的实例(非静态的成员内部类):
//Person.Bird bird = new Person.Bird();//错误的
Person p = new Person();
Person.Bird bird = p.new Bird();


4.2如何在成员内部类中调用外部类的结构?

复制代码

class Person{
    String name = "小明";
public void eat(){
}
//非静态成员内部类
    class Bird{
        String name = "杜鹃";
        public void display(String name){
            System.out.println(name);//方法的形参
            System.out.println(this.name);//内部类的属性
            System.out.println(Person.this.name);//外部类的属性
        //Person.this.eat();
        }
    }
}

复制代码


5.局部内部类的使用:

复制代码

//返回一个实现了Comparable接口的类的对象
    public Comparable getComparable(){
        
        //创建一个实现了Comparable接口的类:局部内部类
        //方式一:
//        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;
            }
            
        };
        
    }

复制代码

注意点:
在局部内部类的方法中(比如:show如果调用局部内部类所声明的方法(比如:method)中的局部变量(比如:num)的话,要求此局部变量声明为final的。
*
jdk 7及之前版本:要求此局部变量显式的声明为final的
jdk 8及之后的版本:可以省略final的声明
总结:
成员内部类和局部内部类,在编译以后,都会生成字节码文件。
格式:成员内部类:外部类$内部类名.class
局部内部类:外部类$数字 内部类名.class

匿名内部类

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

格式:

new 父类构造器(实参列表)|实现接口(){

//匿名内部类的类体部分

}

匿名内部类的特点

 匿名内部类必须继承父类或实现接口

 匿名内部类只能有一个对象

 匿名内部类对象只能使用多态形式引用

复制代码

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.cnblogs.com/hzcya1995/p/13308927.html