• 抽象类


    抽象类

     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 }

    代码执行

      

  • 相关阅读:
    android调试推荐使用BlueStacks模拟器调试Android应用
    目录文件Oracle11g彻底删除
    进程间通信学习APUE学习进程间通信(4)
    android选择Windows 8 下配置Cocos2dx + Android + Eclipse 的开发环境
    windbg API 跟踪
    symchk 获取符号文件(PDB)
    acs for PEAPMSCHAPV2
    peapMSCHAPV2
    vs2005 "Key not valid for use in specified state"
    NetUserGetInfo NetUserAdd
  • 原文地址:https://www.cnblogs.com/FettersLove/p/13741857.html
Copyright © 2020-2023  润新知