谦谦君子,温润如玉!桃李不言,下自成蹊!

why example

抽象类

抽象类

 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)如果子类继承抽象类,没有重写父类中所有的抽象方法,意味着子类中还有抽象方法,那么此子类必须必须声明为抽象的。

img

上面的例子中,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 }

代码执行

  

 

posted @ 2020-09-27 21:11  FettersLove  阅读(208)  评论(0)    收藏  举报
Live2D