1 //abstract 抽象类:类 extends: 单继承 2 public abstract class Action { 3 4 //约束~有人帮我们实现 5 //abstract,抽象方法,只有方法名字,没有方法的实现! 6 public abstract void doSomething(); 7 8 //1.不能new这个抽象类,只能靠子类去实现它:约束 9 //2.抽象类中可以写普通方法 10 //3.抽象方法必须在抽象类中 11 12 } 13 14 15 //抽象类的所有方法,继承了他的子类,都必须要继承它的方法~~除非 16 public abstract class A extends Action{ 17 public void doSomething(){ 18 19 } 20 21 }
例:
public abstract class TestAbstract { //这是一个抽象方法, public abstract void run(); //当然这里面也可以是普通的方法 public void eat() { System.out.println("我是一个在抽象类里面的普通方法"); } }
这里为了区别普通的类,我们一般加abstract这个关键字,我们就认为他是一个抽象类。既然是一个类,那么普通类的属性他都有,它也可以写普通的方法。
这里就有人说了,那这个有什么用呢?没有实现体,就是调用也没用啊,JDK也想到这个了,所以呢他是不让你直接实例化调用的,因为没用啊,对吧,这也是为什么抽象类不可以直接实例化自己,这里说实例化自己有些人不明白,说人话就是不可以自己创建一个自己的对象出来,他只能是子类的引用来创建父类的对象。
举个栗子:
public static void main(String[] args) { /** * 抽象类是不可以自己实例化自己的,只能实例化自己的子类,因为只有子类才有方法的实现,自己实例化自己是没有意义的。况且就是自己 * 里面有普通方法的实现,他的子类都是可以使用的。 */ TestAbstract t = new TestA01(); }
回到之前的话题,既然有些方法不可以实现,写了做什么呢?难道就为了那几个可以实现的方法?当然不是的,这里的抽象类是为了子类更好的实现。
我们举个简单的例子:我们有一个动物的类,里面有一个Run的方法,这个时候我们需要继承他,一只狗说我会跑,老虎说我也会跑,孔雀说我也会跑,这个时候每一个子类都要继承他,而且由于Run方法已经被父类实现了,所以每一个都要重写方法体,是不是很麻烦,这个时候JDK就说了,既然那么多类需要继承他,我直接不实现这个方法,你们谁用谁实现算了。这个就是抽象类存在的意义!
说的比较官方一些的话,就是抽象类可以将设计和实现分离,你写你的抽象类,我写我的实现方法。这也是为什么说抽象方法必须被继承才有意义!
举个栗子:
class TestA01 extends TestAbstract{ /** * @Override 是注解,JDK5.0以后的新特性,重写的意思,也就是说,如果是注解了的话,就是重写的方法,名字是不可以改的, 如果去掉注解,说明不是重写的方法 * 名字是可以改掉的。 */ @Override public void run() { System.out.println("我是子类的run()"); } }
-
有抽象方法的类必然是抽象类
-
抽象类不可以被实例化,不能被new来实例化抽象类
-
抽象类可以包含属性,方法,构造方法,但是构造方法不能用来new实例,只能被子类调用
-
抽象类只能用来继承
-
抽象类的抽象方法必须被子类继承,子类必须写。
注意
一:抽象类(abstract class)
在类的继承中,如果一个个新的子类被定义,子类变得越来越具体,父类变得更加一般和通用,类的设计应该保证父子类能够共享特征,有时将父类设计得非常抽象,使得父类没有具体的实例,这样的类叫做抽象类;一般当我们设计一个类,不需要创建此类的实例时,可以考虑将该类设置成抽象类,让其子类实现这个类的抽象方法
抽象类的特征:
(1) 不可被实例化
(2)抽象类是有构造器的(所有类都有构造器)
(3)抽象方法所在的类,一定是抽象类(因为抽象方法是没有方法体的,如果所在的类不是抽象类,那么该类可以实例化对象,调用抽象方法,然后无方法体去具体实现功能,则矛盾)
(4)抽象类可以没有抽象方法的
1 //抽象类 2 abstract class Person { 3 String name; 4 public Person(){}//抽象类的构造方法 5 public abstract void dink();//抽象方法,无{}方法体 6 public void eat(){ //非抽象方法 7 }; 8 } 9 class Student extends Person{ 10 @Override 11 public void eat() { 12 System.out.println("吃饭"); 13 } 14 15 @Override 16 public void dink() { 17 System.out.println("喝水"); 18 } 19 }
二:抽象方法(abstract method)
abstract修饰的方法为抽象方法
抽象方法的特征:
(1)格式,没有方法体,包括{ },例如 public abstract void dink();
(2)抽象方法只保留方法的功能,具体的执行,交给继承抽象类的子类,由子类重写改抽象方法
(3)如果子类继承抽象类,并重写了父类的所有的抽象方法,则此子类不是抽象类,可以实例化的
(4)如果子类继承抽象类,没有重写父类中所有的抽象方法,意味着子类中还有抽象方法,那么此子类必须必须声明为抽象的。
上面的例子中,Student子类继承抽象父类,自重写了eat()抽象方法,没有重写drink()抽象方法,会报错,解决方法是把drink()方法也重写了,或者把Student也变成抽象类
三:抽象类的使用场景
要求:公司中有程序员和项目经理。程序员有姓名、工号和薪水。并为公司进行工作。项目经理除了有姓名、工号和薪水外还有奖金。也为公司进行工作。对给出的需求进行数据建模。
分析:
程序员:属性:姓名、工号、薪水
行为:工作
项目经理:属性:姓名、工号、薪水、奖金
行为:工作
两者不存在所属关系,但是有共性内容,可以向上抽取为雇员。
雇员:属性:姓名、工号、薪水
行为:工作
1 //抽象类 Employee 2 abstract class Employee 3 { 4 private String name; 5 private int id; 6 private double pay; 7 8 public void setName(String name) 9 { 10 this.name = name; 11 } 12 public void setId(int id) 13 { 14 this.id = id; 15 } 16 public void setPay(double pay) 17 { 18 this.pay = pay; 19 } 20 21 public String getName() 22 { 23 return name; 24 } 25 public int getId() 26 { 27 return id; 28 } 29 public double getPay() 30 { 31 return pay; 32 } 33 34 Employee(String name,int id,double pay) 35 { 36 this.name = name; 37 this.id = id; 38 this.pay = pay; 39 } 40 41 //抽象方法 work 42 public abstract void work(); 43 } 44 45 //描述程序员继承抽象类 Employee 46 class Programmer extends Employee 47 { 48 Programmer(String name,int id,double pay) 49 { 50 super(name,id,pay); 51 } 52 public void work() 53 { 54 System.out.println("name: "+this.getName()+" id: " +this.getId()+" pay: "+this.getPay() ); 55 System.out.println("Programmer work ......"); 56 } 57 58 } 59 60 61 //描述项目经理继承抽象类 Employee 62 class Manager extends Employee 63 64 { 65 private double bonus; 66 67 Manager(String name,int id,double pay,double bonus) 68 { 69 super(name,id,pay); 70 this.bonus = bonus; 71 } 72 public void work() 73 { 74 System.out.println("name: "+this.getName()+" id: " +this.getId()+" pay: "+this.getPay()+" bonus: " +bonus); 75 System.out.println("Manager work ......"); 76 } 77 } 78 79 class AbstractDemo 80 { 81 public static void main(String[] args) 82 { 83 Programmer a = new Programmer("xiaoming",001,5000.00); 84 a.work(); 85 Manager m = new Manager("xiaohong",010,8000.00,600.00); 86 m.work(); 87 } 88 }
代码执行