定义一个抽象类
例子:
1 2 3 4 5 6 7 8 9 10 11
| abstract class A{ private String info = "Hello world"; public void print(){ System.out.println(info); } public abstract void get(); //只声明没有方法体 } public class Test { public static void main(String args[]){ }
|
输出结果:
错误的使用—直接实例化对象
例子:
1 2 3 4 5
| public class Test { public static void main(String args[]){ A a = new A(); //A是抽象的,无法实例化 }
|
输出结果:
思考:为什么抽象类不能够直接new?
答:一个类的对象实例化后,可以调用类中的属性和方法,但是抽象类之中的抽象方法没有方法体,如果这样直接调用,那不就乱了吗?
抽象类的使用原则:
- 抽象类必须有子类,子类用extends继承,只能有一个子类。
- 子类(如果不是抽象类)则必须覆写抽象类之中的全部抽象方法;
- 抽象类对象可以使用对象的向上转型方式,通过子类来进行实例化操作。
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| abstract class A{ private String info = "Hello world"; public void print(){ System.out.println(info); } public abstract void get(); //只声明没有方法体 } class Imp1 extends A{ } public class Test { public static void main(String args[]){ } }
|
输出结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| abstract class A{ private String info = "Hello world"; public void print(){ System.out.println(info); } public abstract void get(); //只声明没有方法体 } class Imp1 extends A{ public void get(){ System.out.println("Hello MLDN"); } } public class Test { public static void main(String args[]){ A a = new Imp1(); //向上转型 a.print(); //自己类定义 a.get(); //子类负责实现 } }
|
输出结果:
结论:通过以上的一个程序,现在可以很清楚的发现,与之前类的继承不一样的是,抽象类的定义又出了子类必须要覆写的方法,而之前的类子类可以有选择的来决定是否需要覆写,而且可以发现,抽象类实际上就比普通类多了一些抽象方法而已,其他的定义和普通类完全一样,如果把抽象类比喻成一盘炒熟的菜,那么抽象类就是一盘半成品。
抽象类的若干种疑问
- 抽象类是否使用final定义?
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| final abstract class A{ private String info = "Hello world"; public void print(){ System.out.println(info); } public abstract void get(); //只声明没有方法体 } public class Test { public static void main(String args[]){ A a = new Imp1(); //向上转型 a.print(); //自己类定义 a.get(); //子类负责实现 } }
|
输出结果:
结论:不能,因为抽象类必须有子类,final定义的类不能有子类,也不能被继承;
- 抽象类之中能否包含构造方法?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| abstract class A{ private String info = "Hello world"; public A(){ System.out.println("*****"); } public void print(){ System.out.println(info); } public abstract void get(); //只声明没有方法体 } class Imp1 extends A{ public void get(){ System.out.println("Hello MLDN"); } } public class Test { public static void main(String args[]){ A a = new Imp1(); //向上转型 a.print(); //自己类定义 a.get(); //子类负责实现 } }
|
输出结果:
结论:可以,因为抽象类之中出了包含抽象方法之外,还包含可普通方法和属性,而属性一定要在构造方法执行完毕之后才可以进行初始化操作;
- 抽象类之中能否不包含抽象方法?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| abstract class A{ private String info = "Hello world"; public A(){ System.out.println("*****"); } public void print(){ System.out.println(info); } } class Imp1 extends A{ public void get(){ System.out.println("Hello MLDN"); } } public class Test { public static void main(String args[]){ A a = new Imp1(); //向上转型 a.print(); //自己类定义 } }
|
输出结果:
结论:可以,抽象类之中可以没有抽象方法,但是反过来讲,如果有抽象方法,则一定是抽象类,即使抽象类之中没有抽象方法,也不能够被直接实例化;
- 抽象类能否使用static声明?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| static abstract class A{ private String info = "Hello world"; public A(){ System.out.println("*****"); } public void print(){ System.out.println(info); } } class Imp1 extends A{ public void get(){ System.out.println("Hello MLDN"); } } public class Test { public static void main(String args[]){ A a = new Imp1(); //向上转型 a.print(); //自己类定义 a.get(); //子类负责实现 } }
|
输出结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| abstract class A{ private String info = "Hello world"; static abstract class B{ //外部类 public abstract void print(); } } class Imp1 extends A.B{ public void print(){ System.out.println("Hello MLDN"); } } public class Test { public static void main(String args[]){ A.B b = new Imp1(); //向上转型 b.print(); } }
|
输出结果:
结论:如果定义的是外部抽象类,则不能够使用static声明,可是如果定义的是外部抽象类,那么这个内部的抽象类使用了static声明之后,就表示是一个外部的抽象类。