继承、多态、抽象、接口

时间:2021-02-03 21:54:04

本文出自:http://blog.csdn.net/dt235201314/article/details/50958173

一、继承

面向对象中代码复用有两种方法,一种被称之为组合,即在一个新的类中使用一个现有的类,比如在新创建的类中又一个String类,一般应用在has-a的关系;还有一种便是继承了,一般用于is-a的关系。

继承是在不改变原有类的情况下,采用原有的类的形式,并向里面添加新的代码而形成的一个新类,新类一般被称为之类,原类被称之为父类。

其中,继承所用到的关键字为 extends,使用过程中也会用到this,super,public,protect,private,final关键字。

下例是继承的用法,并且还包含了一些其他java语法的特性。

[java] view plain copy
  1. class Cleanser{  
  2.   private String s = "Cleanser";  
  3.   public void append(String a) { s+=a;}  
  4.   public void dilute() { append(" dilute()"); }  
  5.   public void apply() { append(" apply()"); }  
  6.   public void scrub() { append(" scrub()"); }  
  7.   public String toString() { return s;}  
  8.   
  9.   public static void main(String[] args){  
  10.       Cleanser x = new Cleanser();  
  11.       x.dilute();x.apply();x.scrub();  
  12.       System.out.println(x);  
  13.     }  
  14. }  
  15.   
  16.  public class Detergent extends Cleanser{  
  17.     //Change a method;  
  18.     public void scrub() {  
  19.         append(" Detergent scrub()");   
  20.         super.scrub(); //call base-class version;   
  21.     }   
  22.     //add methods to the interface;   
  23.     public void foam() {append(" foam()");}   
  24.     //test the new class ;  
  25.     public static void main(String[] args){  
  26.         Detergent x = new Detergent();   
  27.         x.dilute(); x.apply(); x.scrub(); x.foam();   
  28.         System.out.println(x);  
  29.         System.out.print("Testing base class:");  
  30.         Cleanser.main(args);   
  31.     }  
  32. }/* OUTPUT: 
  33. Cleanser dilute() apply() Detergent.scrub() scrub() foam() 
  34. Testing base class: 
  35. Cleanser dilute() apply() scrub() 
  36. *///:~  


在java中,没有C++的析构函数的概念,C++中的析构函数用于销毁创建的对象,需要程序员手动操作,而JAVA中由于垃圾回收机制的存在,对象在合适的时机会自动销毁。

  重载与复写:

当子类出现和父类一模一样的函数时,当子类对象调用该函数,会运行子类函数的内容。如同父类的函数被覆盖一样。这种情况是函数的另一个特性:重写(覆盖)。

       当子类继承父类,沿袭了父类的功能,到子类中。但是子类虽具备该功能,但是功能的内容却和父类不一致,这时,没有必要定义新功能,而是使用覆盖特性,保留父类的功能定义,并重写功能内容。子类同时具有父类方法中的内容时,可以用super.方法();

重载是函数名一样,函数参数列表不一样,与返还值无关;

复写是子类与父类函数一模一样。

public:接口访问权限,表示对每个人都是可用的(每个编译单元都只能拥有一个public 类,且该类的名称必须与编译单元名称一样,包括大小写)。

protect:继承访问权限,表示对派生类可用而不是所有类。

private:表示私有,除了包含该成员的类意外,任何类都无法访问。

final:修饰基本数据表示数值永远不改变,修饰引用时表示引用不变,即初始化指向一个对象之后不能改为指向另一个对象,修饰方法为了锁定方法防止继承类改变它。修饰类时表示不允许该类有子类,即不能被继承。

二、多态

继承,其允许把对象视为自己本身的类型或者基类的类型来处理。而多态,允许一种类型表现出与其他相似类型之间的区别,只要它们是从同一个基类中导出来的,。下面用一个例子来理解:

[java] view plain copy
  1. public enum Note{  
  2.     MIDLE_C,C_SHARP,B_FLAT;  
  3. }  
  4. class Instrument{  
  5.   void play(Note n) {System.out.println("Instrument.play() "+ n);}  
  6.   String what() {return "Instrument";}  
  7.   void adjust() {System.out.println("Adjusting Instrument");}  
  8. }  
  9.   
  10. class Wind extends Instrument{  
  11.     void play(Note n) { System.out.println("Wind.play() "+n);}  
  12.     String what() {return "Wind";}  
  13.     void adjust() {System.out.println("Adjusting Wind");}  
  14. }  
  15.   
  16. class Percussion extends Instrument{  
  17.     void play(Note n) { System.out.println("Percussion.play() "+n);}  
  18.     String what() {return "Percussion";}  
  19.     void adjust() {System.out.println("Adjusting Percussion");}  
  20. }  
  21.   
  22. class Stringed extends Instrument{  
  23.     void play(Note n) { System.out.println("Stringed.play() "+n);}  
  24.     String what() {return "Stringed";}  
  25.     void adjust() {System.out.println("Adjusting Stringed");}  
  26. }  
  27.   
  28. class Brass extends Wind {  
  29.     void play(Note n) { System.out.println("Brass.play()"+n);}  
  30.     void adjust() {System.out.println("Adjusting Brass");}  
  31. }  
  32. class Woodwind extends Wind {  
  33.     void play(Note n) { System.out.println("Woodwind.play()"+n);}  
  34.     void adjust() {System.out.println("Adjusting Woodwind");}  
  35. }  
  36.   
  37. public class Music{  
  38.     //doesn't care about type, so new types  
  39.     //added to the system still work right;  
  40.     public static void tune(Instrument i) {  
  41.         i.play(Note.MIDDLE_C);  
  42.     }  
  43.     public static void tuneAll(Instrument[] e){  
  44.         for(Instrument i:e)  
  45.             tune(i);  
  46.     }  
  47.     public static void main(String[] args){  
  48.         //up casting during addition to the array:  
  49.         Instrument[] orchestra = {  
  50.             new Wind(),  
  51.             new Percussion(),  
  52.             new Stringed(),  
  53.             new Brass(),  
  54.             new Woodwind()  
  55.         };  
  56.         tuneAll(orchestra);  
  57.     }  
  58. /*OUTPUT: 
  59. Wind.play() MIDDLE_C 
  60. Percussion.play() MIDDLE_C 
  61. Stringed.play() MIDDLE_C 
  62. Brass.play() MIDDLE_C 
  63. Woodwind.play() MIDDLE_C 
  64. *///:~  

三、抽象

在上个例子中,基类Instrument(乐器)创建对象并没有多大意义,其目的是为了导出其他子类,子类继承并重写父类的方法从而实现代码复用,我们把类似Instrument的基类称之为抽象类,在C++中有虚基类的概念。抽象类中的方法叫抽象方法,C++中称之为纯虚函数,这种方法是不完整的,只能声明却没有方法体。

语法: abstruct void f(); 用抽象来更改上面的例子:

[java] view plain copy
  1. public enum Note{  
  2.     MIDLE_C,C_SHARP,B_FLAT;  
  3. }  
  4. abstruct class Instrument{  
  5.   private int i;  
  6.   public abstruct void play(Note n);  
  7.   public String what() {return "Instrument";}  
  8.   public abstruct void adjust();}  
  9. }  
  10.   
  11. class Wind extends Instrument{  
  12.     public void play(Note n) { System.out.println("Wind.play() "+n);}  
  13.     public String what() {return "Wind";}  
  14.     public void adjust() {}  
  15. }  
  16.   
  17. class Percussion extends Instrument{  
  18.     public void play(Note n) { System.out.println("Percussion.play() "+n);}  
  19.     public String what() {return "Percussion";}  
  20.     public void adjust() {}  
  21. }  
  22.   
  23. class Stringed extends Instrument{  
  24.     public void play(Note n) { System.out.println("Stringed.play() "+n);}  
  25.     public String what() {return "Stringed";}  
  26.     public void adjust() {}  
  27. }  
  28.   
  29. class Brass extends Wind {  
  30.     public void play(Note n) { System.out.println("Brass.play()"+n);}  
  31.     public void adjust() {System.out.println("Brass.play()");}  
  32. }  
  33. class Woodwind extends Wind {  
  34.     public void play(Note n) { System.out.println("Woodwind.play()"+n);}  
  35.     public String what() { return "Woodwind";}  
  36. }  
  37.   
  38. public class Music{  
  39.     //doesn't care about type, so new types  
  40.     //added to the system still work right;  
  41.     public static void tune(Instrument i) {  
  42.         i.play(Note.MIDDLE_C);  
  43.     }  
  44.     public static void tuneAll(Instrument[] e){  
  45.         for(Instrument i:e)  
  46.             tune(i);  
  47.     }  
  48.     public static void main(String[] args){  
  49.         //up casting during addition to the array:  
  50.         Instrument[] orchestra = {  
  51.             new Wind(),  
  52.             new Percussion(),  
  53.             new Stringed(),  
  54.             new Brass(),  
  55.             new Woodwind()  
  56.         };  
  57.         tuneAll(orchestra);  
  58.     }  
  59. /*OUTPUT: 
  60. Wind.play() MIDDLE_C 
  61. Percussion.play() MIDDLE_C 
  62. Stringed.play() MIDDLE_C 
  63. Brass.play() MIDDLE_C 
  64. Woodwind.play() MIDDLE_C 
  65. *///:~  



四、接口

关键字abstruct 允许在类中创建没有定义的方法——接口部分,但是没有提供具体的实现。interface关键字将产生一个完全抽象的类,该类中的所有方法都是抽象的。我们称这种类为接口。把关键字class用interface代替。

接口中的成员修饰符是固定的:

 成员常量:publicstaticfinal
 成员函数:publicabstract
由此得出结论,接口中的成员都是公共的权限。

[java] view plain copy
  1. public enum Note{  
  2.     MIDLE_C,C_SHARP,B_FLAT;  
  3. }  
  4. interface Instrument{  
  5.   //Compile-time constant;  
  6.   int VALUE = 5;  
  7.   //cannot have method definitions;  
  8.   void play(Note n);  
  9.   void adjust();  
  10. }  
  11.   
  12. class Wind inplements Instrument{  
  13.     public void play(Note n) { System.out.println(this + ".play() "+n);}  
  14.     public String toString() {return "Wind";}  
  15.     public void adjust() {System.out.println(this + ".adjust() ");}  
  16. }  
  17.   
  18. class Percussion inplements Instrument{  
  19.     public void play(Note n) { System.out.println(this + ".play() "+n);}  
  20.     public String toString() {return "Percussion";}  
  21.     public void adjust() {System.out.println(this + ".adjust() ");}  
  22. }  
  23.   
  24. class Stringed inplements Instrument{  
  25.     public void play(Note n) { System.out.println(this + ".play() "+n);}  
  26.     public String toString() {return "Stringed";}  
  27.     public void adjust() {System.out.println(this + ".adjust() ");}  
  28. }  
  29.   
  30. class Brass extends Wind {  
  31.     public String toString() {return "Brass";}  
  32. }  
  33. class Woodwind extends Wind {  
  34.     public String toString() { return "Woodwind";}  
  35. }  
  36.   
  37. public class Music{  
  38.     //doesn't care about type, so new types  
  39.     //added to the system still work right;  
  40.     public static void tune(Instrument i) {  
  41.         i.play(Note.MIDDLE_C);  
  42.     }  
  43.     public static void tuneAll(Instrument[] e){  
  44.         for(Instrument i:e)  
  45.             tune(i);  
  46.     }  
  47.     public static void main(String[] args){  
  48.         //up casting during addition to the array:  
  49.         Instrument[] orchestra = {  
  50.             new Wind(),  
  51.             new Percussion(),  
  52.             new Stringed(),  
  53.             new Brass(),  
  54.             new Woodwind()  
  55.         };  
  56.         tuneAll(orchestra);  
  57.     }  
  58. /*OUTPUT: 
  59. Wind.play() MIDDLE_C 
  60. Percussion.play() MIDDLE_C 
  61. Stringed.play() MIDDLE_C 
  62. Brass.play() MIDDLE_C 
  63. Woodwind.play() MIDDLE_C 
  64. *///:~