分享一下我对抽象类的认识:

  一、认识抽象类

public abstract class Shape {
    
}

我们在普通的类上加入一个abstract(抽象的),这个类就变成了抽象类。

二、抽象类和普通类的区别

思考一下,在我们学习多态的时候,是不是都有讲到通过向上转型后,通过引用调用重写方法然后发现调用到了子类的重写方法?

public  class Shape {
       public void draw(){
           System.out.println("画了一个图形");
       }
}
public class Rect extends Shape{
    @Override
    public void draw() {
        System.out.println("画了一个矩形");
    }
}
public class Test {
    public static void main(String[] args) {
     Shape shape = new Rect();
     shape.draw();//发生动态绑定,调用到了子类的重写方法
    }
}

在我们讲到这种动态绑多现象的时候,有没有发现,其实这个父类的draw方法基本没有实现过,我们都在专心研究怎么通过多态,调用子类的而非父类的draw方法,那么这个父类的draw方法其实没有什么意义了,我们可不可以就写个 public void draw();呢?系统肯定会报错,这个时候就引出抽象类这一概念了,我们在父类Shape的class前加一个abstract

public abstract class Shape {

}

1.抽象类可以有抽象方法,普通方法,普通成员等(注意是可以有,没有也不会报错)

2.如果一个类中有抽象方法,那么这个类一定是抽象类

3.普通类只有普通变量和普通方法,子类不重写这个普通父类里的方法时不会报错

public abstract class Shape {
       public abstract void draw();
}

我们在抽象类中将draw方法也变成抽象方法,这个方法就可以没有具体实现了,不过记住!!!子类在继承父类Shape这个抽象类后,必须要重写父类里面的抽象方法,否则系统会报错。

普通类可以直接实例化对象,但抽象类不行

public class Test {
    public static void main(String[] args) {
   Shape shape = new Shape();//此时Shape类不是抽象类,只是一个普通类
    }
}

当Shape是一个普通类时,可以实例化对象

public abstract class Shape {

}
public class Test {
    public static void main(String[] args) {
   Shape shape = new Shape();//系统报错
    }
}

可当Shape变为抽象类时,不能实例化对象了,除了这几点,很多地方还是跟普通类差不太多的。

三、抽象类,抽象方法存在的意义

首先记住,抽象类的存在就是为了被其他类继承,抽象方法的存在就是为了被重写(子类继承不全部重写完就报错,除非这个子类也成为抽象类,那么抽象父类里的抽象方法不再强制要求全部重写),所以千万不要拿 final 去修饰抽象类和抽象方法,final会使得这个类不再能被继承,方法不再能被重写,这恰恰违背了其抽象类和抽象方法存在的意义,所以不能拿final去修饰

static 也不能和 abstract 共存,被 static 修饰的方法不能被子类重写,这也和 abstract 设计意图完全冲突。

思考一下,在没讲抽象类的时候,我们普通类完全能做到这些功能,为什么还要讲和用抽象类呢?

抽象类很严格,如果子类继承抽象父类不重写父类的全部的抽象方法的话系统就会报错,报错是因为编译器的校验,而我们使用抽象类就是为了编译器的校验,目的是通过编译器来监督我们子类到底有没有重写抽象父类里的抽象方法,记住,充分利用编译器的校验,在实际开发中非常有价值。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐