抽象类和接口的区别(概念)

抽象类:     

     1、由abstract修饰的方法为抽象方法,抽象方法只有方法的定义,没有方法的实现。

        2、一个类中如果包含抽象方法,这个类应该用abstract关键字声明为抽象类。

        3、抽象类不可以实例化,即使一个类中没有抽象方法,也可以将其定义为抽象类,同样,该类不可以实例化。

   抽象类的意义:
         1、为子类提供一个公共的类型;
         2、封装子类中重复内容(成员变量和方法);
         3、定义有抽象方法,子类虽然有不同的实现,但该方法的定义是一致的。      

 

举个例子:

              1、假设有2个类,一个类是主力球员(NormalPlayer),一个类是替补球员(SubPlayer)。

 1 public class NormalPlayer
 2     {
 3         public int ID { get; set; }
 4         public string FirstName { get; set; }
 5         public string LastName { get; set; }
 6         public decimal WeekSalary { get; set; }
 7         public string GetFullName()
 8         {
 9             return this.FirstName + " " + this.LastName;
10         }
11         public decimal GetDaySalary()
12         {
13             return W
14 public class SubPlayer
15     {
16         public int ID { get; set; }
17         public string FirstName { get; set; }
18         public string LastName { get; set; }
19         public decimal MonthSalary { get; set; }
20         public string GetFullName()
21         {
22             return this.FirstName + " " + this.LastName;
23         }
24         public decimal GetWeekSalary()
25         {
26             return Mo

 

              2、NormalPlayer和SubPlayer有共同的属性和方法,当然也有不同的属性和方法。把2个类的共同部分抽象出一个基类(基类就是父类)。

 1 public class BasePlayer
 2     {
 3         public int ID { get; set; }
 4         public string FirstName { get; set; }
 5         public string LastName { get; set; }
 6         
 7         public string GetFullName()
 8         {
 9             return this.FirstName + " " + this.LastName;
10         }
11     }

              3、然后让先前的2个类派生于这个基类。

 1 public class NormalPlayer: BasePlayer
 2     {
 3         public decimal WeekSalary { get; set; }
 4         public decimal GetDaySalary()
 5         {
 6             return WeekSalary/7;
 7         }
 8     }
 9     public class SubPlayer : BasePlayer
10     {
11         public decimal MonthSalary { get; set; }
12         public decimal GetWeekSalary()
13         {
14             return MonthSalary/4;
15         }
16     }

              4、接着,我们发现NormalPlayer和SubPlayer计算日薪和周薪的方法也可以抽象出来,作为虚方法放到基类中。

 1 public class BasePlayer
 2     {
 3         public int ID { get; set; }
 4         public string FirstName { get; set; }
 5         public string LastName { get; set; }
 6         
 7         public string GetFullName()
 8         {
 9             return this.FirstName + " " + this.LastName;
10         }
11         public virtual decimal GetSalary()
12         {
13             throw new NotImplementedException();
14       

              5、在NormalPlayer和SubPlayer这2个派生类中,需要重写基类的虚方法。

 1 public class NormalPlayer: BasePlayer
 2     {
 3         public decimal WeekSalary { get; set; }
 4         //获取日薪
 5         public override decimal GetSalary()
 6         {
 7             return WeekSalary / 7;
 8         }
 9     }
10     public class SubPlayer : BasePlayer
11     {
12         public decimal MonthSalary { get; set; }
13         //获取周薪
14         public override decimal GetSalary()
15         {
16          

              6、在实际情况中,BasePlayer只是一个抽象出来的类,我们并不希望实例化这个类。这时候,就可以把BasePlayer设计为abstract抽象类。同时,在抽象类中,提供一个计算薪水的抽象方法。一旦在基类中声明了没有方法体的抽象方法,所有派生于这个抽象类的类必须实现或重写基类中的抽象方法。

 1 public abstract class BasePlayer
 2     {
 3         public int ID { get; set; }
 4         public string FirstName { get; set; }
 5         public string LastName { get; set; }
 6         
 7         public string GetFullName()
 8         {
 9             return this.FirstName + " " + this.LastName;
10         }
11         public abstract decimal GetSalary();
12     }

总结,当2个或多个类中有重复部分的时候,我们可以抽象出来一个基类,如果希望这个基类不能被实例化,就可以把这个基类设计成抽象类。

 

 

接口(Interface):是一系列方法的声明,是一些方法特征集合,一个接口只有方法没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)

 

   1、接口的含义: 

(1) Java接口没有任何的实现,因为java接口比涉及表象,而只描述public行为,所以java接口比抽类更加的抽象化。                     

(2)Java接口的方法只能是抽象的和公开的,java接口不能有构造器,java接口可以有public,静态的final属性。 

(3)接口支持多继承。

    2.、接口的特点:

      1、java接口中的成员变量默认都是public static final类型的(都可以省了),必须被显示初始化,即接口中的成员变量为常量(大写,单词之间用 “_”分隔) 

      2、 java接口中的方法默认都是public abstract类型的(都可省了),没有当方法体,不能被实例化。
      3、 java接口只能包含public static final类型的成员变量 和public abstract类型的成员方法
      4、 接口中没有构造方法,不能被实例化
      5、 一个接口不能实现另外一个接口,但可以继承多个其他接口
      6、 Java接口必须通过类来实现他的抽象方法
      7、 当类实现了某个java接口时,它必须实现接口中的所有抽象方法,否则这个类必须声明为抽象类(也就是说如果抽类实现了某个接口的时候,可以不实现该接口里面的方法)
      8、 不允许创建接口的实例(实例化),但允许定义接口类型的引用变量,该引用变量引用实现这个接口的类的实例 

      9、 一个类只能继承一个直接的父类,但可以实现多个接口,间接的实现了多继承。

 

共同点:他们都可以实现多态。
不同点:抽象类是为继承而精心设计的(为了被子类继承,为子类提供了同一的方法入口),接口则更多以组合的方式使用。

               

 

举个Demo:                  

          使用abstract class的方式定义Demo抽象类的方式如下:

 

                   abstract class Demo{
                          abstract void method1(); 
                          abstract void method2(); 
                             …
                      }   

         使用interface的方式定义Demo抽象类的方式如下:

                    interface Demo{
                          void method1();
                          void method2();
                            …
                       }

 

posted @ 2018-04-16 12:59  毫无代价  阅读(517)  评论(0)    收藏  举报