java关键字abstract(抽象)详解
说到抽象,想必⼤家第⼀个联想到的就是抽象画,基本上看不懂画的是啥,只能说它在表达某个概念。
在java中我们中abstract关键字来表达抽象。举个例⼦:
我们说车⼦都可以跑(run)。但有⼏个轮⼦,怎么跑,对于不同的车有不同的结果。⾃⾏车需要⼈踩着跑,汽车发动机推动跑等等,那么我们可以车表达为抽象类。
/**
* 车⼦类
*/
public abstract class Car {
public abstract void run();
}
/**
* ⾃⾏车
*/
class Bicycle extends Car{
@Override
public void run() {
System.out.println("⼈踩着跑。。。");
}
}
/***
* 汽车
*/
class Automobile extends Car{
@Override
public void run() {
System.out.println("发动机驱动跑。。。");
}
}
假如后⾯各种车,倒着跑、悬在空中跑随你怎么跑,只需要继承抽象类实现⾃⼰的业务就⾏了。相信⼤家对java抽象已有⼀个初步的印象了。
抽象⽅法:
1、从上⾯的例⼦中我们可以看到抽象⽅法跟普通⽅法是有区别的,它没有⾃⼰的主体(没有{}包起来的
业务逻辑),跟接⼝中的⽅法有点类似。所以我们没法直接调⽤抽象⽅法
2、抽象⽅法不能⽤private修饰,因为抽象⽅法必须被⼦类实现(覆写),⽽private权限对于⼦类来
说是不能访问的,所以就会产⽣⽭盾
3、抽象⽅法也不能⽤static修饰,试想⼀下,如果⽤static修饰了,那么我们可以直接通过类名调
⽤,⽽抽象⽅法压根就没有主体,没有任何业务逻辑,这样就毫⽆意义了。
抽象类:
1、⽤abstract关键字来表达的类,其表达形式为:(public)abstract class 类名{}
2、抽象类不能被实例化,也就是说我们没法直接new ⼀个抽象类。抽象类本⾝就代表了⼀个类型,⽆法确定为⼀个具体的对象,所以不能实例化就合乎情理了,只能有它的继承类实例化。
3、抽象类虽然不能被实例化,但有⾃⼰的构造⽅法(这个后⾯再讨论)
4、抽象类与接⼝(interface)有很⼤的不同之处,接⼝中不能有实例⽅法去实现业务逻辑,⽽抽象类
中可以有实例⽅法,并实现业务逻辑,⽐如我们可以在抽象类中创建和销毁⼀个线程池。
5、抽象类不能使⽤final关键字修饰,因为final修饰的类是⽆法被继承,⽽对于抽象类来说就是
需要通过继承去实现抽象⽅法,这⼜会产⽣⽭盾。(后⾯将写⼀篇关于finally的⽂章详细讨论)
抽象类与抽象⽅法的关联:
如果⼀个类中⾄少有⼀个抽象⽅法,那么这个类⼀定是抽象类,但反之则不然。也就是说⼀个抽象类中可以没有抽象⽅法。这样做的⽬的是为了此类不能被实例化。
如果⼀个类继承了⼀个抽象类,那么它必须全部覆写抽象类中的抽象⽅法,当然也可以不全部覆写,如果不覆写全部抽象⽅法则这个⼦类也必须是抽象类(这样做就⽆意义了)
public abstract class Car {
public void mothod1(){
}
public abstract void mothod2();
public abstract void method3();
}
class Bicycle extends Car{
@Override
public void mothod2() {//需要覆写抽象⽅法mothod2
}
@Override
public void method3() {//需要覆写抽象⽅法mothod3
}
}
抽象类的构造器:
先来看⼀个例⼦:
public abstract class Car {
Car(){
System.out.println("抽象⽅法⽆参构造函数");
}
Car(String a){
System.out.println("抽象有参构造⽅法");
}
public void mothod1(){
System.out.Class());
System.out.println("抽象类的实例⽅法");
}
public abstract void mothod2();
}
/**
* ⾃⾏车
*/
class Bicycle extends Car{
Bicycle(){
System.out.println("⼦类⽆参构造函数");
}
@Override
public void mothod2() {//需要覆写抽象⽅法mothod2
}
}
/**另⼀个包的测试类**/
public class Test {
public static void main(String[] args) {
Bicycle b = new Bicycle();
}
}
结果:
抽象⽅法⽆参构造函数java接口有没有构造方法
⼦类⽆参构造函数
class com.shaolin.service.impl.Bicycle
抽象类的实例⽅法
从上⾯的例⼦中可以看出:
1、抽象类是有构造⽅法的(当然如果我们不写,编译器会⾃动默认⼀个⽆参构造⽅法)。⽽且从结果来看,和普通的继承类⼀样,在new ⼀个⼦类对象时会优先调⽤⽗类(这⾥指的是抽象类Car)的构造器初始化,然后再调⽤⼦类的构造器。⾄此相信⼤家都会有这样⼀个疑问,为什么抽象⽅法不能实例化却有构造器呢? 对于这个问题⽹上也中说纷纭,没有确定答案。
我是这样想的:既然它也属于继承的范畴,那么当⼦类创建对象时必然要优先初始化⽗类的属性变量和实例⽅法,不然⼦类怎么继承和调⽤呢?⽽它本⾝不能实例化,因为它本⾝就是不确定的⼀个对象,如果它能被实例化,那么我们通过它的对象来调⽤它本⾝的抽象⽅法是不是有问题。所以不能实例化有在情理之中。因此⼤家只要记住这个规定就⾏。
2、对于抽象类中的⾮statci(静态)和⾮abstract(抽象)⽅法中的this关键字(静态⽅法中不能有关键字this之前已经讨论过可以参考)代表的是它的继承类,⽽⾮抽象类本⾝,这个好理解,因为抽象类本⾝不能被实例化。如果有多个继承类,谁调⽤this就代表谁。
抽象类有什么好处呢?
1、由于抽象类不能被实例化,最⼤的好处就是通过⽅法的覆盖来实现多态的属性。也就是运⾏期绑定
2、抽象类将事物的共性的东西提取出来,由⼦类继承去实现,代码易扩展、易维护。
以上部分逻辑纯属个⼈观点,如有不正还望指出,谢谢!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论