抽象类:

1.普通类:可以直接产生实例化对象,并且在普通类中可以包含构造方法、普通方法、static放、常量、变量的内容。
2.抽象类:指在普通类的结构里面增加抽象方法的组成部分,抽象方法指的是没有方法体的方法,同时抽象方法还必须使用abstract关键字定义。
3.拥有抽象方法的类一定属于抽象类,抽象类要使用abstract声明。
首先我们定义一个抽象类:

abstract class A {
    public void fun() {
        System.out.println("存在有方法体的方法!");
    }
    public abstract void print() ;
}

我们可以看到print()方法并没有方法体的声明,并且存在abstract关键字,表示抽象方法。

抽象类只是比普通类多了抽象方法的定义,其他结构与普通类完全一样。

注意:抽象类不能直接实例化对象。
若要使用抽象类:
1.抽象类必须有子类,即每一个抽象类类一定要被子类所继承(使用extends关键字),但是在java中每一个子类只能够继承一个抽象类,所以具备继承局限。
2.抽象类的子类(子类不是抽象类)必须覆写抽象类中全部的抽象方法(强制子类覆写)。
3.依靠对象的向上转型概念,可以通过抽象类的子类完成抽象类实例化对象的操作。
正确使用抽象类:

abstract class A {
    public void fun() {
        System.out.println("存在有方法体的方法!");
    }
    public abstract void print() ;
}
class B extends A {
    public void print() {
        System.out.println("Hello,world!");

    }
}
public class TestDemo {
    public static void main(String args[]) {
        A a = new B() ;
        a.print() ;
    }
}

本程序为抽象类定义了一个子类B,而子类B是一个普通类必须覆写抽象类中的所有抽象方法,所以就在主方法中依靠子类对象的向上转型实现了抽象类A对象的实例化操作,而调用的print()方法被子类覆写,所以最终调用的是子类B覆写过的print()方法。
强调: 1.抽象类不能使用final定义,因为抽象类必须有子类,而final定义的类不能有子类。
2.抽象类中可以没有任何抽象方法,但只要是抽象类,就不能直接使用关键字new实例化对象。
没有抽象方法的抽象类:

abstract class A {
    public void fun() {
        System.out.println("!!!!");
    }
}
class X extends A {
}
public class TestDemo {
    public static void main(String args[]) {
        A a = new X() ;
        a.fun() ;
    }
}

本程序抽象类A中没有定义任何抽象方法,但A类依然无法直接实例化,必须利用子类对象的向上转型才能为抽象类实例化对象。
定义抽象类的内部类:

abstract class A {
	abstract class B{
    public abstract void print() ;
	}
}
class X extends A {
    public void print() {
        System.out.println("Hello,world!");
	 }
	 class Y extends B {
		 public void print(){
	 	}
	 }
}

本程序在抽象类A中定义了一个抽象类B,而在定义A的子类X时不一定非要定义内部类Y。当然也可以定义一个内部类Y,可以直接继承内部的抽象类B。
强调:
外部抽象类不允许使用static声明,而内部的抽象类允许使用static声明,使用static声明的内部版抽象类相当于是一个外部抽象类,继承时使用“外部类.内部类”的形式表示类名称。
利用static定义的内部类为外部抽象类:

abstract class A {
    static abstract class B {
        public abstract void print () ;
    }
}
class X extends  A.B {
    public void print() {
        System.out.println("!!!");
    }
}
public class TestDemo {
    public static void main(String args[]) {
        A.B ab = new X () ;
        ab.print() ;
    }
}

本程序利用static在抽象类A中定义了一个抽象类B。这样就相当于B是一个外部类,则X类就可以直接使用“A.B”的名称继承这个外部类。
在抽象类中,若定义了static属性或方法时,就可以在没有对象的时候直接调用。

abstract class A {
        public static void print () {
            System.out.println("!!!");
    }
}

public class TestDemo {
    public static void main(String args[]) {
        A.print();
    }
}

本程序在抽象类中定义了一个static方法,由于static方法不受实例化对象的限制,所以可以直接由类名称调用。