抽象类

抽象方法指的是没有方法体的方法,同时它还必须被abstract关键字修饰,拥有抽象方法的类一定是抽象类。抽象类一定要使用abstract申明,抽象类是不能直接被实例化的,由于抽象类的方法没有方法体,实例化之后也就没法执行了。所有没有意义

  1. abstract class A {//抽象类
  2. public abstract void print();//抽象方法
  3. }
  • 抽象类一定要有子类,每一个抽象类一定要被子类覆写
  • 抽象类的子类(子类不是抽象类)必须覆写抽象类里面的全部方法。
  • 抽象类的实例化需要依靠子类完成,采用向上转型的方式处理
  • 一个子类只能继承一个抽象类,单继承。
  1. abstract class A {//抽象类
  2. public abstract void print();//抽象方法
  3. }
  4. class B extends A{
  5. public void print(){
  6. System.out.println("hello");
  7. }
  8. }
  9. public class TestDemo{
  10. public static void main(String[] args){
  11. A a = new B();//向上转型
  12. a.print();
  13. }
  14. }

使用限制

  • 抽象类由于会存在一些属性,所以抽象类中一定存在构造方法,子类实例化时依然满足先执行父类构造方法在执行子类构造方法的情况。

  • 抽象类不能用final 定义,应为抽象类必须有子类,final 定义的类不能有子类

  • 抽象类外部的抽象类不运行使用static 声明,而内部抽象类允许使用static 申明,使用static申明的内部抽象类就相当于一个外部抽象类,继承的时候使用外部类.内部类的形式表示类名称。

    1. abstract class A {//抽象类
    2. static abstract class B {
    3. public abstract void print();//抽象方法
    4. }
    5. }
    6. class C extends A.B{
    7. public void print(){
    8. System.out.println("hello");
    9. }
    10. }
    11. public class TestDemo{
    12. public static void main(String[] args){
    13. A.B ab = new C();//向上转型
    14. ab.print();
    15. }
    16. }
  • 抽象类可以有static方法,如下:

    1. abstract class A {//抽象类
    2. public static void print{
    3. System.out.println("hello");
    4. }
    5. }
    6. public class TestDemo{
    7. public static void main(String[] args){
    8. A.print();//可以直接调用
    9. }
    10. }
  • 我们有时候不想多写一个继承类,同时也不需要外部知道这个子类存在,那么可采用如下方法。

    1. abstract class A {//抽象类
    2. public abstract void print();//抽象方法
    3. private static class B extends A{
    4. public void print(){
    5. System.out.println("hello");
    6. }
    7. }
    8. public static B newInstance(){
    9. return new B();
    10. }
    11. }
    12. public class TestDemo{
    13. public static void main(String[] args){
    14. A.newInstance.print();//可以直接调用
    15. }
    16. }

有关抽象类的一个问题

如下:这样调用输出的结果是num=0,这是由与执行 A a = new B(40);时,默认先执行父类构造,那么这个时候由于构造函数还没初始化完成,所以变量都是其对应类型的初始值,即int的初始值是0.

关键点:类的所以属性赋值都是在构造函数执行完成后开始的

  1. abstract class A {//抽象类
  2. public A(){//2.执行父类构造
  3. this.print();//3.执行该方法会跳到子类去执行
  4. }
  5. public abstract void print();//抽象方法
  6. }
  7. class B extends A{
  8. int num = 100;
  9. public B(int num){
  10. this.num = num;
  11. }
  12. public void print(){//4.子类执行该方法
  13. System.out.println("num=" + this.num);
  14. }
  15. }
  16. public class TestDemo{
  17. public static void main(String[] args){
  18. A a = new B(40);//1.new B
  19. }
  20. }

总结

  • 抽象类规定了子类必须要做的事情,而且可以与抽象类的普通方法结合使用
  • 抽象类单继承