抽象方法和抽象类
1.抽象方法:
(1)用abstract修饰的方法,没有方法体,只有声明。
(2)抽象方法必须用public或者protected,缺省情况下默认为public;
2.抽象类:
(1)概念:包含了抽象方法的类就是抽象类。
在网上看到一个觉得不错的例子,引入方便理解
在生活中,你肯定用过这个词语--东西
“麻烦你,小王。帮我把那个东西拿过来好吗?”
“你要让我拿那个水杯吗?”
你要的是水杯类的对象,而东西是水杯的父类,通常东西类(这里理解为抽象类)没有实例对象,但我们有时需要东西的引用来指向它的之类实例。
(2)特点:不能创建实例
(3)意义
抽象类更利于代码的维护和重用。
维护:比如本科和研究生可以抽象成学生,他们有相同的属性和方法。这样当你对其中某个类进行修改时会受到父类的限制,这样就会提醒开发人员有些东西不能进行随意修改,这样可以对比较重要的东西进行统一的限制,也算是一种保护,对维护会有很大的帮助。
重用:比如学校又新产生了专科生这类学生,那么专科生直接继承学生,然后对自己特有的属性和方法进行补充即可。这样对于代码的重用也是很好的体现。
(4)注意
- 有抽象方法的类只能定义成抽象类
- 抽象类不能实例化
- 抽象类可以包含属性、方法和构造器,但是构造器不能用new来实例化,只能用来被之类调用
- 抽象类只能用来被继承
- 抽象方法必须被之类实现
- 抽象类不能用final声明,因为抽象类必须有子类,而final定义的类不能有子类
- 子类对象实例化的时候,先执行父类的构造方法,再执行子类的构造方法
abstract class A{//定义一个抽象类
public A(){
System.out.println("*****A类构造方法*****");
}public abstract void print();//抽象方法,没有方法体,有abstract关键字做修饰
}
//单继承
class B extends A{//B类是抽象类的子类,是一个普通类public B(){
System.out.println("*****B类构造方法*****");
}
@Override
public void print() {//强制要求覆写
System.out.println("Hello World !");
}
}
public class TestDemo {public static void main(String[] args) {
A a = new B();//向上转型
}}
执行结果:
*****A类构造方法*****
*****B类构造方法*****
- 外部抽象类不允许使用static声明,而内部的抽象类可以使用static声明。
-
//外部类
static abstract class A{//定义一个抽象类
public abstract void print();
}class B extends A{
public void print(){
System.out.println("**********");
}
}
public class TestDemo {public static void main(String[] args) {
A a = new B();//向上转型
a.print();
}}
执行结果:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Illegal modifier for the class A; only public, abstract & final are permittedat com.wz.abstractdemo.A.<init>(TestDemo.java:3)
at com.wz.abstractdemo.B.<init>(TestDemo.java:9)
at com.wz.abstractdemo.TestDemo.main(TestDemo.java:18)
内部类:
abstract class A{//定义一个抽象类
static abstract class B{//static定义的内部类属于外部类
public abstract void print();
}
}class C extends A.B{
public void print(){
System.out.println("**********");
}
}
public class TestDemo {public static void main(String[] args) {
A.B ab = new C();//向上转型
ab.print();
}}
执行结果:
**********
- 有时候由于抽象类中只需要一个特定的系统子类操作,所以可以忽略掉外部子类。这样的设计在系统类库中会比较常见,目的是对用户隐藏不需要知道的子类。
abstract class A{//定义一个抽象类
public abstract void print();
private static class B extends A{//内部抽象类子类
public void print(){//覆写抽象类的方法
System.out.println("Hello World !");
}
}
//这个方法不受实例化对象的控制
public static A getInstance(){
return new B();
}
}public class TestDemo {
public static void main(String[] args) {
//此时取得抽象类对象的时候完全不需要知道B类这个子类的存在
A a = A.getInstance();
a.print();
}
}
执行结果:
Hello World !