抽象类和接口的区别(概念)
抽象类:
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(); 
                            …
                       }
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号