关于实例化抽象类的讨论

抽象类可不可以实例化?

从广义上来讲,抽象类可以被实例化,从狭义上讲,抽象类不能被实例化,接下来我们将从这两个方面展开讨论.

1.普通类的实例化

我们首先创建一个普通类Person,

public class Person{
    public void study(){
        System.out.println("我爱学习");
    }
}

然后再创建一个测试类Test,用于测试Person的实例化.

public class Test{
    public static void main(String[] args){
        Person person = new Person();
        person.study();
    }
}

运行程序,成功地输出了”我爱学习”,说明成功的调用了Person中的方法study(),person即为类Person的实力化对象.

2.抽象类的实例化
既然普通类可以通过new关键字实例化对象,那么抽象类是否可以呢?
我们首先创建一个抽象类AbstractPerson

public abstract class AbstractPerson{
    public abstract void study();
}

然后在测试类中测试实例化AbusractPerson

public class Test{
    public static void main(String[] args){
        Person person = new Person();
        person.study();

        AbstractPerson aPerson = new AbstractPerson();//Error
    }
}

当我们模仿普通类创建AbstractPerson的实例化对象时,编译器给我们来了个报错,为什么会报错呢?
这里写图片描述
告诉我们AbstractPerson是抽象类,不能被实例化,我们就这样放弃了吗?还有没有别的办法?
当然有!我们可以使用匿名内部类将抽象类中的抽象方法实现,这样不就可以对其实例化了.

public class Test {
    public static void main(String[] args){
        Person person = new Person();
        person.study();

        AbstractPerson aPerson = new AbstractPerson(){

            @Override
            public void study() {
                System.out.println("我在抽象地学习");
            }
        };
        aPerson.study();
    }
}

运行程序得到以下输出
我爱学习
我在抽象地学习

类比普通类的实例化,我们得到了相同的效果,是不是说抽象类可以被实例化了?从广义上来说,我们完成了对抽象类的实例化,但深入了解的话是不是这样呢?

3.抽象类实例化的剖析

在IDEA中,可以使用ctrl+H可以查看类的关系,我们在AbstractPerson类中使用此快捷键可以看到下图:
这里写图片描述
可以看到在AbstractPerson类下面多了一个类,可是我们的列表中并没有这个类,这个其实就是我们实现抽象方法的时候所建立的匿名内部类,可见我们创建的实例化对象其实是这个匿名内部类的,并不是AbstractPerson抽象类的实例化对象.
如何佐证这一点呢,我们使用equal方法来判断我们得到的实例化对象到底属不属于AbstractPerson类.

在Test类中补充如下代码

public class Test {
    public static void main(String[] args){
        Person person = new Person();
        person.study();

        AbstractPerson aPerson = new AbstractPerson(){

            @Override
            public void study() {
                System.out.println("我在抽象地学习");
            }
        };
        aPerson.study();
        System.out.println(
                aPerson.getClass().equals(AbstractPerson.class));
        //判断aPerson所属的类与AbstractPerson是否相同,若相同返回true
    }
}

运行 返回false 说明aPerson并不是AbstractPerson的实例化对象

总结
我们通过匿名内部类成功的创建了可以调用AbstractPerson中方法的实例化对象,但它并不属于AbstractPerson,而是属于我们创建的匿名内部类,实际上调用的是匿名内部类中的方法,从广义上讲,我们通过匿名内部类成功实例化了AbstractPerson,但从狭义上讲,我们实例化的只是那个匿名内部类.
关于抽象类能否被实例化一致就有两种声音,我们不应该纠结于这个问题的结果,应该通过问题看到抽象类和匿名内部类之间的关系,再具体运用的时候,我们可以通过匿名内部类快速创建一个指向抽象类的对象,而不用再创建一个类实现其方法,同时我们也应该理解所创建对象真正的归属.

以上皆是本人在学习JAVA中的一些见解,如有错误,欢迎指正
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值