设为首页 加入收藏

TOP

关于Java中的匿名内部类及内部类
2019-01-25 14:09:42 】 浏览:117
Tags:关于 Java 匿名 部类

匿名内部类适合创建那些只需要使用一次的类,它的语法有些奇怪,创建匿名内部类会立即创建一个该类的实例,这个类定义立即消失,且不能重复使用。


定义匿名类的格式如下:


从定义来看,匿名内部类必须继承一个父类,或者实现一个接口,但是最多只能继承一个父类或者实现一个接口。


关于匿名内部类,还有如下两条规则:


下面给出了一个常见的匿名内部类的使用示例:


public class Main {
    public static void main(String[] args){
        Main main = new Main();
        main.test(new Man(){
            //这里传入一个Man接口的匿名实现类的实例
            public void talk(){
                System.out.print("I'm a man!");
                //output I'm a man!
            }
        });
    }
   
    public void test(Man m){
        //调用该方法需要传入一个Man类型参数
        m.talk();
    }
}


interface Man{
    void talk();
}


定义一个匿名内部类无需使用class关键字,而是在定义匿名内部类时直接生成该匿名内部类的对象。


由于匿名内部类不能是抽象类,所以匿名内部类必须实现它的抽象父类或者接口里包含的抽象方法。


虽然上面的例子完全可以采用使用实现类对象的方法来完成相同的功能,但是明显使用匿名内部类更加简洁。


当通过实现接口来创建匿名内部类时,匿名内部类不能显式创建构造器,因此匿名内部类只有一个隐式的无参数构造器,故new接口名后的括号中不能传入参数。


但是如果通过继承父类来创建匿名内部类时,匿名内部类将拥有和父类相似的构造器,注意此处相似的构造器指的是拥有相同形参列表。


下面是通过继承父类来创建匿名内部类的示例:


public class Main {
    public static void main(String[] args){
        Main main = new Main();
        main.test(new Man("Amos H"){
            //这里传入一个Man接口的匿名实现类的实例
            public void talk(){
                System.out.println(this.getName());
                //output Amos H
            }
            public int getHight(){
                return 175;
            }
        });
    }
   
    public void test(Man m){
        //调用该方法需要传入一个Man类型参数
        m.talk();
    }
}


abstract class Man{
    private String name;
    public Man(String name){
        this.name = name;
    }
    public void talk(){
        System.out.println(name);
    };
    public String getName(){
        return name;
    }
    public abstract int getHight();
}


可以看到,创造匿名内部类可以使用和父类相同的参数列表,调用父类的构造器。


当创建匿名内部类时,必须实现接口或者抽象父类中的所有抽象方法。如果有必要的话,可以重写父类中的普通方法。


内部类的二三事:


非静态内部类对象必须寄生在外部类对象中,而外部类对象则不一定有非静态内部类对象寄生其中。因此外部类对象不能访问非静态内部类对象,而非静态内部类对象可以访问外部类成员,因为存在内部类必然存在外部类。


非静态内部类对象不可以有静态初始化块,但是可以有普通初始化块。非静态内部类普通初始化块的作用与外部类初始化块的作用完全相同。


因为静态内部类是外部类的类相关的,而不是外部类的对象相关的。静态内部类对象不是寄生在外部类的实例中,而是寄生在外部类的类本身中。当静态内部类对象存在时,并不一定存在一个被它寄生的外部类对象,静态内部类对象只持有外部类的类引用,并没有持有外部类对象的引用。如果允许静态内部类的实例方法访问外部类的实例成员,但找不到被寄生的外部类对象,这将引起错误。


非静态内部类的子类不一定是内部类,它也可以是一个外部类。但是非静态内部类的子类实例一样要保留一个引用,该引用用于指向其父类所在外部类的对象。也就是说,如果一个内部类子类的对象存在,则一定存在与之对应的外部类对象。因为要实例化一个非静态内部类的语法通常是这样的:


Out.In in = new Out().new In();


可以看到,非静态内部类的构造器必须使用外部类对象来调用。


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Linux网络编程之一个简单的socket.. 下一篇详解Java中对象的软、弱和虚引用..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目