本文出自:http://blog.csdn.net/dt235201314/article/details/50958173
一、继承
面向对象中代码复用有两种方法,一种被称之为组合,即在一个新的类中使用一个现有的类,比如在新创建的类中又一个String类,一般应用在has-a的关系;还有一种便是继承了,一般用于is-a的关系。
继承是在不改变原有类的情况下,采用原有的类的形式,并向里面添加新的代码而形成的一个新类,新类一般被称为之类,原类被称之为父类。
其中,继承所用到的关键字为 extends,使用过程中也会用到this,super,public,protect,private,final关键字。
下例是继承的用法,并且还包含了一些其他java语法的特性。
- class Cleanser{
- private String s = "Cleanser";
- public void append(String a) { s+=a;}
- public void dilute() { append(" dilute()"); }
- public void apply() { append(" apply()"); }
- public void scrub() { append(" scrub()"); }
- public String toString() { return s;}
- public static void main(String[] args){
- Cleanser x = new Cleanser();
- x.dilute();x.apply();x.scrub();
- System.out.println(x);
- }
- }
- public class Detergent extends Cleanser{
- //Change a method;
- public void scrub() {
- append(" Detergent scrub()");
- super.scrub(); //call base-class version;
- }
- //add methods to the interface;
- public void foam() {append(" foam()");}
- //test the new class ;
- public static void main(String[] args){
- Detergent x = new Detergent();
- x.dilute(); x.apply(); x.scrub(); x.foam();
- System.out.println(x);
- System.out.print("Testing base class:");
- Cleanser.main(args);
- }
- }/* OUTPUT:
- Cleanser dilute() apply() Detergent.scrub() scrub() foam()
- Testing base class:
- Cleanser dilute() apply() scrub()
- *///:~
在java中,没有C++的析构函数的概念,C++中的析构函数用于销毁创建的对象,需要程序员手动操作,而JAVA中由于垃圾回收机制的存在,对象在合适的时机会自动销毁。
重载与复写:
当子类出现和父类一模一样的函数时,当子类对象调用该函数,会运行子类函数的内容。如同父类的函数被覆盖一样。这种情况是函数的另一个特性:重写(覆盖)。
当子类继承父类,沿袭了父类的功能,到子类中。但是子类虽具备该功能,但是功能的内容却和父类不一致,这时,没有必要定义新功能,而是使用覆盖特性,保留父类的功能定义,并重写功能内容。子类同时具有父类方法中的内容时,可以用super.方法();
重载是函数名一样,函数参数列表不一样,与返还值无关;
复写是子类与父类函数一模一样。
public:接口访问权限,表示对每个人都是可用的(每个编译单元都只能拥有一个public 类,且该类的名称必须与编译单元名称一样,包括大小写)。
protect:继承访问权限,表示对派生类可用而不是所有类。
private:表示私有,除了包含该成员的类意外,任何类都无法访问。
final:修饰基本数据表示数值永远不改变,修饰引用时表示引用不变,即初始化指向一个对象之后不能改为指向另一个对象,修饰方法为了锁定方法防止继承类改变它。修饰类时表示不允许该类有子类,即不能被继承。
二、多态
继承,其允许把对象视为自己本身的类型或者基类的类型来处理。而多态,允许一种类型表现出与其他相似类型之间的区别,只要它们是从同一个基类中导出来的,。下面用一个例子来理解:
- public enum Note{
- MIDLE_C,C_SHARP,B_FLAT;
- }
- class Instrument{
- void play(Note n) {System.out.println("Instrument.play() "+ n);}
- String what() {return "Instrument";}
- void adjust() {System.out.println("Adjusting Instrument");}
- }
- class Wind extends Instrument{
- void play(Note n) { System.out.println("Wind.play() "+n);}
- String what() {return "Wind";}
- void adjust() {System.out.println("Adjusting Wind");}
- }
- class Percussion extends Instrument{
- void play(Note n) { System.out.println("Percussion.play() "+n);}
- String what() {return "Percussion";}
- void adjust() {System.out.println("Adjusting Percussion");}
- }
- class Stringed extends Instrument{
- void play(Note n) { System.out.println("Stringed.play() "+n);}
- String what() {return "Stringed";}
- void adjust() {System.out.println("Adjusting Stringed");}
- }
- class Brass extends Wind {
- void play(Note n) { System.out.println("Brass.play()"+n);}
- void adjust() {System.out.println("Adjusting Brass");}
- }
- class Woodwind extends Wind {
- void play(Note n) { System.out.println("Woodwind.play()"+n);}
- void adjust() {System.out.println("Adjusting Woodwind");}
- }
- public class Music{
- //doesn't care about type, so new types
- //added to the system still work right;
- public static void tune(Instrument i) {
- i.play(Note.MIDDLE_C);
- }
- public static void tuneAll(Instrument[] e){
- for(Instrument i:e)
- tune(i);
- }
- public static void main(String[] args){
- //up casting during addition to the array:
- Instrument[] orchestra = {
- new Wind(),
- new Percussion(),
- new Stringed(),
- new Brass(),
- new Woodwind()
- };
- tuneAll(orchestra);
- }
- } /*OUTPUT:
- Wind.play() MIDDLE_C
- Percussion.play() MIDDLE_C
- Stringed.play() MIDDLE_C
- Brass.play() MIDDLE_C
- Woodwind.play() MIDDLE_C
- *///:~
三、抽象
在上个例子中,基类Instrument(乐器)创建对象并没有多大意义,其目的是为了导出其他子类,子类继承并重写父类的方法从而实现代码复用,我们把类似Instrument的基类称之为抽象类,在C++中有虚基类的概念。抽象类中的方法叫抽象方法,C++中称之为纯虚函数,这种方法是不完整的,只能声明却没有方法体。
语法: abstruct void f(); 用抽象来更改上面的例子:
- public enum Note{
- MIDLE_C,C_SHARP,B_FLAT;
- }
- abstruct class Instrument{
- private int i;
- public abstruct void play(Note n);
- public String what() {return "Instrument";}
- public abstruct void adjust();}
- }
- class Wind extends Instrument{
- public void play(Note n) { System.out.println("Wind.play() "+n);}
- public String what() {return "Wind";}
- public void adjust() {}
- }
- class Percussion extends Instrument{
- public void play(Note n) { System.out.println("Percussion.play() "+n);}
- public String what() {return "Percussion";}
- public void adjust() {}
- }
- class Stringed extends Instrument{
- public void play(Note n) { System.out.println("Stringed.play() "+n);}
- public String what() {return "Stringed";}
- public void adjust() {}
- }
- class Brass extends Wind {
- public void play(Note n) { System.out.println("Brass.play()"+n);}
- public void adjust() {System.out.println("Brass.play()");}
- }
- class Woodwind extends Wind {
- public void play(Note n) { System.out.println("Woodwind.play()"+n);}
- public String what() { return "Woodwind";}
- }
- public class Music{
- //doesn't care about type, so new types
- //added to the system still work right;
- public static void tune(Instrument i) {
- i.play(Note.MIDDLE_C);
- }
- public static void tuneAll(Instrument[] e){
- for(Instrument i:e)
- tune(i);
- }
- public static void main(String[] args){
- //up casting during addition to the array:
- Instrument[] orchestra = {
- new Wind(),
- new Percussion(),
- new Stringed(),
- new Brass(),
- new Woodwind()
- };
- tuneAll(orchestra);
- }
- } /*OUTPUT:
- Wind.play() MIDDLE_C
- Percussion.play() MIDDLE_C
- Stringed.play() MIDDLE_C
- Brass.play() MIDDLE_C
- Woodwind.play() MIDDLE_C
- *///:~
四、接口
关键字abstruct 允许在类中创建没有定义的方法——接口部分,但是没有提供具体的实现。interface关键字将产生一个完全抽象的类,该类中的所有方法都是抽象的。我们称这种类为接口。把关键字class用interface代替。
接口中的成员修饰符是固定的:
成员常量:publicstaticfinal
成员函数:publicabstract
由此得出结论,接口中的成员都是公共的权限。
- public enum Note{
- MIDLE_C,C_SHARP,B_FLAT;
- }
- interface Instrument{
- //Compile-time constant;
- int VALUE = 5;
- //cannot have method definitions;
- void play(Note n);
- void adjust();
- }
- class Wind inplements Instrument{
- public void play(Note n) { System.out.println(this + ".play() "+n);}
- public String toString() {return "Wind";}
- public void adjust() {System.out.println(this + ".adjust() ");}
- }
- class Percussion inplements Instrument{
- public void play(Note n) { System.out.println(this + ".play() "+n);}
- public String toString() {return "Percussion";}
- public void adjust() {System.out.println(this + ".adjust() ");}
- }
- class Stringed inplements Instrument{
- public void play(Note n) { System.out.println(this + ".play() "+n);}
- public String toString() {return "Stringed";}
- public void adjust() {System.out.println(this + ".adjust() ");}
- }
- class Brass extends Wind {
- public String toString() {return "Brass";}
- }
- class Woodwind extends Wind {
- public String toString() { return "Woodwind";}
- }
- public class Music{
- //doesn't care about type, so new types
- //added to the system still work right;
- public static void tune(Instrument i) {
- i.play(Note.MIDDLE_C);
- }
- public static void tuneAll(Instrument[] e){
- for(Instrument i:e)
- tune(i);
- }
- public static void main(String[] args){
- //up casting during addition to the array:
- Instrument[] orchestra = {
- new Wind(),
- new Percussion(),
- new Stringed(),
- new Brass(),
- new Woodwind()
- };
- tuneAll(orchestra);
- }
- } /*OUTPUT:
- Wind.play() MIDDLE_C
- Percussion.play() MIDDLE_C
- Stringed.play() MIDDLE_C
- Brass.play() MIDDLE_C
- Woodwind.play() MIDDLE_C
- *///:~