abstract关键里用来声明抽象类和抽象方法,本文主要对相关知识做一些总结
什么是抽象类
通过类的继承性可以知道,随着类被一层一层的继承,类也变得越来越具体。而类的设计应该保证父类和子类由一些能够共享的属性或方法。有时候就需要将父类设计得非常抽象,以至于它没有具体的实例,这样的类就叫做抽象类
比如设计一个描述人的父类people,每一个人都需要有自己职业、技能等等,且再每个子类再继承是都要对这些内容进行重写,父类自定义的方法子类中都要进行重写。这时people类更像是其他子类的一个模板,这是就可以将people类声明为一个抽象类,然后让子类去具体化。
抽象类的使用
Java语言中使用abstract来定义一个抽象类
1 | abstract class Person{ |
以上就创建了一个Person的抽象类,但是如果写如下语句:
1 | Person p1 = new Person();//Cannot instantiate the type Person |
将会报错,这说明匿名类是不可以被实例化的,也就是说抽象类中虽然提供了构造器,但是不能直接实例化一个抽象类。抽象类的使用需要借助其一个一般子类(非抽象)。
1 | class Student extends Person{ |
Student类中提供了一个空参构造器和一个调用了其父类构造器的一个有参构造器,这说明抽象类中的构造器可以被其子类调用,也就是说抽象类可以通过实例化。
此外Student类中还重写了Person类中的display方法,这里直接调用的是Person类中的display方法,这说明其抽象类中的方法和属性同样可以被子类继承。
1 | Student stu = new Student("jone",22); |
抽象方法
虽然上面Person类没有语法问题,但是上面的写法并不能显示出抽象类的设计目的。一般抽象类除了会提供一些具体的方法之外,还会提供提供一些抽象方法,以告诉子类,哪些内容是你必须要有的。
1 | abstract class Person{ |
这里就定义了两个抽象方法(eat和display方法),他们都没有具体的方法体只有一个方法的声明,这是如果直接通过子类调用这个方法,虽然编译不会报错,但是运行时会报错。
实际上子类也会同时报错
1 | Student stu = new Student("jone",22); |
这是我们可以在子类中对这两个方法进行重写,就不会报错
1 | class Student extends Person{ |
但是如果子类中没有对父类中的抽象方法全部进行重写,或者子类中也存在抽象方法,则这个子类就必须时抽象列才可以。
使用abstract的其他注意点
- abstract方法不能用来修饰属性、构造器等结构
抽象就意味着形态的不确定,显然是不能构造一个形态不确定的对象的
- abstract不能用来修饰私有方法、静态方法、final的方法和类
因为私有方法是不能被子类调用的,这样子类就不知道就不知道父类中有几个抽象方法了。静态方法是随着类的加载而加载的,但是加载时却没有不知道要做什么,这显然会出毛病。final意味着最终的,而抽象方法和类还没“开始”呢!
本文链接: https://quandongli.github.io/post/d70ea8f9.html
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!
