abstract是什么意思

更新时间:2022-11-24 23:04:16 阅读: 评论:0


2022年11月24日发(作者:翰林学院)

Java抽象类详解

在中,介绍了抽象⽅法与接⼝,以及做了简单的⽐较。

这⾥我想详细探讨下抽象类。

⼀、抽象类的定义

被关键字“abstract”修饰的类,为抽象类。(⽽且,abxtract只能修饰类和⽅法)

下⾯显⽰了⼀个最简单的空抽象类

publicabstractclassAbstractClass{

publicstaticvoidmain(String[]args){

AbstractClassabstractClass=newAbstractClass();

}

}

当对这个空的抽象类进⾏实例化时,编译器会报错:

'AbstractClass'isabstract;cannotbeinstantiated'

现在对这个抽象类进⾏扩展,添加属性和⽅法:

publicabstractclassAbstractClass{

publicintconstInt=5;

/*重载method()*/

publicvoidmethod(){}

//没有编译错误

publicabstractvoidmethod(inta);

publicstaticvoidmain(String[]args){

AbstractClassabstractClass=newAbstractClass(){

@Override

publicvoidmethod(inta){

n("实例化抽象类");

}

};

n(nt);

(5);

}

}

//运⾏结果

/*

5

实例化抽象类

*/

在这个抽象类中我添加了⼀个实例属性,⼀个抽象⽅法,以及该抽象⽅法的重载实例⽅法,这些都是合法的。

在main⽅法中,直接对抽象类通过new操作符进⾏实例化,出乎意料的是,IDE直接提⽰了这种操作——这⾥⽣成了⼀个(Anonymous

Inner)。

下⾯是关于匿名内部类的知识点:

⼀种特殊的局部内部类,没有类名,没有class关键字,也不能使⽤extends和implements等关键字修饰。

匿名内部类不能是抽象类(即不能拥有抽象⽅法),必须实现它的抽象⽗类或者接⼝的所有抽象⽅法。

因为没有类名,所以匿名内部类只能被使⽤⼀次,通常⽤来简化代码编写。

使⽤匿名内部类的前提条件:继承⼀个⽗类或者实现⼀个接⼝。

第四点和第⼀点略有⽭盾,其实就是使⽤的时候通过new操作符指定要继承的⽗类或要实现的接⼝(事实上,new是直接调⽤某个构造

函数。new真的是个⽜逼的操作符啊),然后再通过直接定义类体(类体中实现某些⽅法),构建新类的实例。

所以,在我上⾯的代码中,⽣成了⼀个继承AbstractClass的新匿名内部类的实例,这个类中实现了⽗类的抽象method⽅法,获得的实

例我们赋给了abstractClass,并通过实例调⽤了新的method(int5)⽅法。

⼆、抽象类与抽象⽅法

抽象⽅法只有⽅法声明,没有⽅法体的⽅法。它将由⼦类(可能是抽象类,也可能是⾮抽象类)进⾏实现。

通过上⾯空的抽象类的⽅法可知,拥有⼀个抽象⽅法并不是构建⼀个抽象类充分必要条件。

那么,⼀个有抽象⽅法的普通类是合法的吗?⼤概率是不合法的,因为如果这样的设计是合法的⼜有什么意义呢?

实际上,如果我们在⼀个⾮抽象类中定义⼀个抽象⽅法,IDE会提⽰:

“Abstractmethodinnon-abstractclass”

⽽如果我们⼀定要运⾏如下所⽰的⼀段错误代码:

publicclassAbstractTest{

publicabstractvoidtest();

publicstaticvoidmain(String[]args){

}

}

编译器的报错信息为:

Error:java:AbstractTest不是抽象的,并且未覆盖ctTest中的抽象⽅法test()

所以抽象⽅法只能存在于抽象类中。

三、抽象⽅法可以是static的吗?

在进⾏下⾯的测试时,突然想到⼀个很有意思的问题,抽象类中的抽象⽅法可以是静态的吗?

先下结论:NO,这是的修饰符组合是不合法的——Error:java:⾮法的修饰符组合:abstract和static

publicabstractclassAbstractTest{

//⾮法的修饰符组合

publicstaticabstractvoidtest();

publicstaticvoidmain(String[]args){

}

}

static成员⽅法意味着,不需要实例化可以使⽤(在类的内部或者通过类访问)。但是呢,也可以通过实例进⾏访问,这样做不会报

错,但会得到IDE的警告,因为违反了static的设计语义;

abstract⽅法意味着没有⽅法体(区别下“有⽅法体,但⽅法体为空”),即只是⼀个⽅法声明,需要被⼦类去实现。

我们先要清楚,抽象类中是可以拥有static⽅法的,⽐如,我们把main⽅法放在⼀个抽象类中,程序是可以由此运⾏的。

既然这样,⼀个“staticabstract”组合的⽅法,对这个抽象类完全没有存在的意义了!!因为它没有⽅法体,⽆法通过类来使⽤。

在StackOverFlow上有探讨,说完全可以允许这样的“staticabstract”⽅法,因为在⾮抽象⼦类中,实现这个抽象⽅法后的⼦⽅法仍然是

static,是⼦类的类⽅法。

这样的说法有⼀点点意义,但是它仍然⽆法解决的是,“staticabstract”⽅法对⽗类中“static”语义的违背

static⽅法可以被⼦类重写吗?

答案是:static⽅法不能被⼦类重写。(涉及到重写的定义)

但是!我们确实⼜可以在⼦类中重新定义⼀个与⽗类static⽅法⼀模⼀样的⽅法,如下的test()⽅法。

onstruct;

publicclassAbstractTest{

publicstaticvoidtest(){

n("ThisisAbstractTest'sstatictest!");

}

publicstaticvoidprint(){

n("ThisisAbstractTest'sstaticprint!");

}

publicstaticvoidmain(String[]args){

();

();

();

n();

AbstractTestSonabstractTestSon=newAbstractTestSon();

();

();

}

}

classAbstractTestSonextendsAbstractTest{

publicstaticvoidtest(){

n("ThisisAbstractTest-Son'sstatictest!");

}

}

//输出

/*

ThisisAbstractTest'sstatictest!

ThisisAbstractTest-Son'sstatictest!

ThisisAbstractTest'sstaticprint!

ThisisAbstractTest'sstaticprint!

ThisisAbstractTest-Son'sstatictest!

*/

通过输出结果可以看到:⽗类中未被⼦类重写的static⽅法是可以被⼦类及其对象访问到的,但是被⼦类重写过的⽅法,则⼦类及其对

象只能调⽤⾃⼰的⽅法了。

为什么这种情况不能叫做⼦类“重写”了⽗类的⽅法呢,⽽是叫”⽅法隐藏(methodhidding)“?

在的这篇⽂章中,对此做了解释:

因为,⽅法重写(Overriding)是OOP语⾔的⼀种特性,在Java中,它是实现“运⾏时多态”⼀种⽅式!!⽽⽗类⼦类的相同签名的同名

⽅法的情况,therewon’tbeanyrun-timepolymorphism。

还篇⽂章(),解释了这些概念的差别,但是却没有提到上述的methodhidding情况。(所以我以为隐藏只是继承关系的类中变量之间

的⾏为)。

四、抽象类的继承

从抽象⽗类派⽣的⼦类如果不能实现所有的抽象⽅法,它也必须声明为抽象的。

抽象类可以定义构造⽅法,且能被⼦类在构造⽅法中调⽤。

⼀个⾮抽象类的⼦类,可以声明为抽象类。

五、final与abstract的⽭盾

final关键字可以修饰类、⽅法、变量。

final修饰的类不能被派⽣;final修饰的⽅法,禁⽌⼦类重写。

所以我们可以看出,final和abstract就是冰⽕不容的~

本文发布于:2022-11-24 23:04:16,感谢您对本站的认可!

本文链接:http://www.wtabcd.cn/fanwen/fan/90/14813.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

上一篇:zoom怎么读
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图